I have a set of utility LabVIEW VIs that make calls to a custom DLL written in C++. I'd like to package the VIs into a LabVIEW toolkit and deploy it via an installer, but am unsure about the standard practices involved in doing this where a custom DLL is involved. I've looked at VIPM for packaging the VIs, but so far I haven't found a way to generate a package and include the appropriate DLL dependencies. What is the correct way to go about generating an installer for a LabVIEW Toolkit and installing the DLL dependency for said toolkit in the correct location (where ever that may be)?
The DLLs immediately known to the system - i.e., the ones entered in the CLFN node - are added automatically.
DLLs which are used indirectly and DLLs which are determined programmatically cannot be auto-included and must be added manually to the Source files section of the respective Build rule.
Related
We are developing audio plugins which are dynamic libraries. This made it very hard to use 3rd-party libraries such as Qt, as our product DLL would search for Qt's DLL on host DAW program's executable directory, and it is impossible to install our dependent DLLs to that position (you don't know which host will be used, and host may even be installed later than the plugin).
I've made some brief search on this problem, the few answers direct me to a Microsoft technology called side-by-side assembly, and I'm almost drawn in the huge documentation and concepts on that. So my question is:
How to make my DLL to load several specific dependent DLLs located at path_to_plugin/MyPlugin_dependents/xxx.dll?
Or is there any examples to side-by-side assembly that simply do this and is much simpler than the official example?
I've created a program and would like to release it, but am currently struggling with dll dependency issues. How can I create a msi installer package that will properly install .dlls? Every solution I've found online so far has created msi packages that only include the exe.
Short Answer: Generally, the most common runtimes are: Java, Visual Studio C/C++ Runtime, .NET Framework. Try installing these on a clean virtual and try launching your application. Debugging application launch check-list.
Modern Deployment: Many Microsoft runtimes that we used to deploy are now part of Windows. An exception is the Visual Studio C/C++ runtimes. I am not sure why they are not just included in Windows at this point. In general you should not pick single dll files to deploy, you need to locate a merge module, a setup.exe or an MSI to deploy the runtime. Commercial tools have features to help you download such bundles.
Setup: The basic, general steps to create a setup are described here: How to create a windows installer for multi language program with outside dependencies?
Specific Runtimes: One can generally determine runtime requirements by looking at the application files (experience - trained eye), looking at the application GUI (visual clues), checking dependencies using dependency scanner tools, talking to the developers of the application, checking file properties of files you find to depend upon (Company name is a good clue), etc... Then you verify and test this on a clean, virtual machine. You keep installing runtimes manually until your application works. In the section "The Complexity of Deployment" here you can find a listing of common runtimes and technologies.
My software is written in VB6. For diagnostic purposes I need to determine the actual DLL / OCX files which are loaded and used by the application on a customer's computer.
Since VB6 DLLs (including OCX files) are COM libraries they are loaded indirectly based on information in the registry. This means it is possible that a different file is being used than what was used in development / testing environments. Sometimes in a client environment this can cause malfunctions which are hard to diagnose without this information.
(My plan is to build a diagnostic readout window in my program that shows the libraries that the program is using at that moment.)
You can use the Dependency Walker to find which DLL your program depend on.
But the OCX are not so easy to find because they are loaded at run-time based on the application dependencies and the registered components through the Windows registry. But you have to already know which OCX components your application references - from the Tools > References and all the places you call CreateObject.
There are many ways in which runtime dependencies on DLLs (or OCX files) can be established. Ideally you would need to account for all of them:
This answer is specific to VB6 but many other programming languages would work similarly.
Mechanisms which establish runtime dependencies:
At Compile time for traditional dynamically-linked libraries (DLLs which are not COM)
Files are (as their name suggests) dynamically loaded at runtime based on the linking process done at the end of compilation
This includes VB6 code which has used a statement like: Declare Function … Lib …
(In .NET this would mean calling out into “native code”)
To identify: Inspect the source code.
To identify without sources: These can be detected by a tool like Dependency Walker
At Compile time for COM DLLs
In VB6 this is known as “early binding”.
This includes VB6 code which has explicitly set a reference to a DLL or OCX.
Note that the dependency is actually on the COM class or interface GUID, and not explicitly on the DLL file itself.
To identify: These are listed in the project VBP.
To identify (alternate): If you don't have the VBP or source code, these dependencies can generally be revealed by by IMPORT statements in OLEView. You might need to look up some GUIDs from there in the registry to see what actual DLL files are used.
At Compile time for statically-linked libraries (not COM, not DLLs)
Library code is included in the EXE or DLL which is being compiled. Therefore there is no runtime dependency to anything external.
As far as I am aware, this is not possible for VB6 programs. Something like a C linker could use libraries like this. A rough equivalent in .NET would be using ILMerge to combine assemblies.
At Runtime for traditional DLLs (not COM)
DLLs can be loaded arbitrarily using Win32 API such as LoadLibrary().
To identify: You have to look at the source to know what might happen.
Alternately if you don't have the source you could use tools like Process Explorer and/or Process Monitor to observe a running instance and see what DLLs actually get loaded.
At Runtime for COM DLLs
Classes can be loaded arbitrarily using eg VB6 CreateObject() calls.
In VB6 this is known as “late binding”
Which DLL will be used to provide the class will be determined by the process’s activation context. The activation context is established by the app manifest file (if there is one) or the Windows registry otherwise (the normal default for VB6 programs).
To identify: You have to look at the source to know what might happen. You also need to know what the configuration state will be on the PC that runs the code - which DLL files are registered, assuming a manifest is not used.
Alternative for no source code: as in the case above
Important: dependencies can be chained. So really you need to "walk the links" of all the dependencies until you build up a complete mapping of what is required. Somewhere in that mapping you can draw a line between what you need to deploy and what the operating system or other runtime environment can be relied on to provide. (IMO for VB6, that line should be drawn rather liberally).
You may be thinking that all this makes the task very difficult or tedious – I totally agree. :)
I have a DLL written in C# and set for COM visibility. I have it setup as a side-by-side assembly and can successfully deploy the application to client PCs registration free. My question is related to the development PC. Is it possible to compile against the DLL in a similar registration-free manner or is registration required on the development machine? I have tried adding the DLL directly though the Project -> References menu and get an error stating "Can't add a reference to the specific file." The DLL is sitting in the same directory as the .vbp file and I have tried adding the DLL both with and without the client app manifest being present.
I have tried adding the DLL directly though the Project -> References menu
That adds a reference to a type library. A type library is a language-independent description of the types in a COM component, VB6 uses it to know how generate efficient code and to provide type checking and auto-completion. A type library is the exact equivalent of metadata in a .NET assembly.
Traditionally, and the way VB6 did it, the type library was embedded as a resource in a DLL. So you are probably used to picking a DLL in the dialog. That however doesn't work so well when the DLL is generated by C#, the type library can only be generated after the C# code is compiled. You have to pick the .tlb file in the VB6 dialog. The traditional way starts with the COM component being described in the IDL language, the type library can be generated before the code is compiled so can easily be embedded in the final DLL. It is technically possible to do it in C# as well, but the build steps are very laborious and painful, you essentially have to build the DLL twice with different build commands.
The type library for a C# library is normally generated in one of three ways:
Using Project + Properties, Build tab, "Register for COM interop" option. This requires VS to run elevated so it can write to the registry. You start VS elevated by right-clicking its shortcut and picking "Run as Administrator"
By running Regasm.exe, using the /tlb:filename option. An alternative for the 1st bullet and necessary if you don't want to run VS elevated for some reason. Using the /codebase option on your dev machine is also wise to make it work exactly like the 1st bullet and not require putting the DLL into the GAC with gacutil.exe
By running the Tlbexp.exe utility, the type library exporter for .NET assemblies. No registration is done, it only generates the .tlb file.
The first bullet is the normal choice and very desirable because you can never forget to update the type library this way. It is perfectly fine on a dev machine since you only really care about reg-free deployment on the user's machine. You probably got into trouble by not doing this anymore.
Using the 3rd choice is okay and more compatible with your goals, run Tlbexp from the Visual Studio Command Prompt. Just keep in mind that you have to do it again when you make changes to your C# code. Forgetting this once and losing clumps of head-hair trying to figure out why your C# changes don't seem to be effective or getting hard-to-diagnose error codes gives you lots of reasons to consider the 1st bullet again :) You can emulate the reg-free scenario by running Regasm.exe with the /uninstall option.
I developped a vb6 program then I build an installation wizard with visual studio interdev.
I used "dependency walker" and "process explorer" to find out the missing DLLs but there is always a problem with :
IESHIMS.DLL
WER.DLL
MPR.DLL
These dlls shown by dependency walker.
And when installing the program on another machine I have these error messages :
uxtheme.dll failed to register
msdatsrc.tlb failed to register etc..
PS : no problem on a machine where visual studio is installed.
Any Idea to fix this issue?
Thanks
Dependency Walker is not an appropriate tool to troubleshoot VB6 dependencies. It works well enough for DLLs written in C or C++ that use implicit dependencies. Although it hasn't kept up with the times and has trouble with DLLs that are stored in the Windows side-by-side cache or are delay loaded. Delay loading is what generates the warnings on ieshims.dll et al.
VB6 uses COM, which loads DLLs dynamically with LoadLibrary(). You'll never see such a dependency back in Depends unless you use the Profile option. Such DLLs are found back through the registry, the reason you needed to write an installer and tinker with regsvr32.exe.
You have to be pretty careful when writing installers like that, VB6 is old and can depend on operating system components that have been updated many times since 1998. Like uxtheme.dll, an important operating system DLL that implements visual styles. Having your installer overwrite the existing one on the user's machine is, well, disastrous. Although it is probably protected by Windows through its File System Protection feature, something that got added as a counter-measure against broken installers.
Giving proper advice is here difficult beyond "do no harm". A commercial installer like InstallShield or Wise (which I liked back then) is the best way to avoid shooting off the customer's leg. Fairly sure they still support VB6 installs. Microsoft makes a pre-cooked installer available for VB6 that installs all the core vb6 runtime components. You can download it here.
You should ALWAYS double check and verify any dependancies that you think your application needs.
All the files you mentioned are system DLLs and MUST NOT be distributed.
For a VB6 application you need the basic runtimes, and any DLLs you explicitly reference/use if and only if you have permission from the authors of those DLLs and instructions on the correct procedure and location for installing them.
For the standard Microsoft provided OCX files, these normally just need to be copied to the system32 folder and registered.
See redist.txt in the root of your Visual Studio installation for more details.