I am refactoring an old installshield application and I need to perform a action that calls a function from a custom dll. Unfortunately the function that this action performs depends on another custom dll. So my question is:"Is it possible to have a custom dll depend on another custom dll and if so how?"
When I try to run the installer it crashes with the error "Setup was interrupted before being complete..." Then I copied the second custom dll to a folder that I added to PATH and everything went fine. Of course I can not expect my customer to do that by hand.
I am using Installshield 2008 but I believe the answer to my question will be the same for all versions.
EDIT: as maybe my question is not clear enough I will give example:
Let's say I have a.dll that has a function:
UINT __stdcall
PerformAction(MSIHANDLE hInstall) // IN
{
...
help();
...
}
help() is defined in b.dll. Now when I create a new action I set it's dll to be a.dll and it's function name to be PerformAction but there is no way to indicate this depends on b.dll
When I copy b.dll to a folder included to PATH the installer works ok but if I don't it fails.
The easiest InstallShield approach here is to use support files instead of or in addition to binary table entries. Windows Installer will only extract a single DLL for a custom action, but if you reference a file in SUPPORTDIR, it can use more than one.
Related
In a Windows Installer custom action a DLL file is called which receives data from the Setup using the MsiGetProperty function.
Is it possible to use such a DLL file outside a Windows Installer Setup? If it is, how can I set the properties/data a certain function of the DLL file needs?
Yes, but you need the right expectations. Unless you have an Installer handle, which you receive when called in the context of an Installer, many of the Windows Installer APIs, including MsiGetProperty, cannot be used.
Depending on your exact needs, I would suggest splitting your implementation into three functions. One is the core implementation. Any values you currently retrieve with MsiGetProperty could be arguments to this function. Any logging should be done through a helper that you can configure to use alternate means, etc. This function need not be exported by your DLL.
The other two functions should then be fairly thin wrappers around this function. They get the values in whichever way makes sense for how they are invoked, and pass them to the core implementation. These two functions are exported.
Then call the appropriate function for your usage, and the bulk of your DLL can be easily shared across both custom action and non-custom action invocations.
I have msi setup that was created in installshield and I am executing the DTF custom action dll as a commit custom action. If I insert MessageBox.Show into the custom action, I can see that there is a temporary folder inside [PROGRAMFILESDIR] called "CustomActionProject.CA.dll-" and there is copied CustomActionProject.CA.dll with all its references.
Is there any way to tell the technology not to create this temp folder and extract+execute the CustomActionProject.CA.dll in the same folder where is .CA.dll located?
Edit:
I found out that I can not include the references in .CA.dll by configuring wix.ca.targets. Which prevents .CA.dll to contain 20MB of dlls in my case.
Now I would like to make sure that CustomActionProject.dll will be able to see the references that are installed with the product.
The files are:
<ProgramFilesFolder>
<MyApplicationFolder>
CustomActionProject.CA.dll
... About 30 dlls installed with the application that CustomActionProject.dll needs to call
<Place I Would Like to See CustomActionProject.dll extracted>
DTF automatically extracts it's files to a temp folder for execution and then cleans up on disposal. This is very good in that it eliminates certain race conditions. You can still author those files into your installer if you like. For example, at a previous company, our installer used several DLL's for license checking during the install and installed them for use by the application at runtime.
BTW, make sure you've seen this:
WiX DTF Behavior Alert
Your custom action was programmed in a managed .Net language (probably C# or VB.Net). As msi files may only contain dll custom actions comprised of native code the DTF tools, specifically the tool makesfxca.exe, packs / wraps the managed dll together with helper code resulting in a self extracting, native code dll. Following WIX´s naming convention the native custom action dll contains an .CA infix.
In order for this (i.e. having custom actions written in languages producing managed code) to work, self extraction has to take place. So the short answer to your question is "No".
My DTF project contains some embedded resources and I would like to access the same in the CustomAction.
I tried the following code in the Custom Action method
// Gets the current assembly.
Assembly Asm = Assembly.GetExecutingAssembly();
// Resources are named using a fully qualified name.
Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);
However this doesnt work as Asm always refers to the Wix Setup assembly and not the custom action dll which contains the resources
Why not use Assembly.GetAssembly(typeof(CustomAction));, to get the assembly that contains your custom action?
To be honest, I'm not sure this scenario is possible. I mean, there might be no option (or no easy option) to get the custom action executing assembly and extract the resources out of it.
Instead of this, I would try to re-design the solution and move resources to the Binary table in MSI package. Thus, you'll still have embedded resources, but not in CA DLL, but in the MSI package itself. The DTF.chm help file contains a sample how to extract files from Binary table - it's a matter of a couple of lines of code.
I'm trying to interact with a .dll which will allow me to receive information from a variety of devices (Eye Gaze to be specific). The .dll is called ETUDriver and can be found at http://www.sis.uta.fi/~csolsp/projects.php however it does not come with an accompanying .h file.
I am struggling to actually load, interact and invoke functions from the .dll. A manual is supplied but it is of no help whatsoever with regards to actually setting up the code to start it off. There are three accompanying example apps (with source code) but only two of these work and one of which is in C# so is not helpful. The one that works however loads up the .dll via MFC and this is not a viable option with my code (which is intended to be used with many other projects and as such can't enforce MFC or any other libraries that are not as standard to projects).
Essentially, within the .dll is a series of classes which I need to create within my code and invoke the relevant functions of that class.
I've tried to use HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(__uuidof(ETUDSink), NULL, CLSCTX_INPROC, __uuidof(IETUDSink), (LPVOID*)&pETUDSink);
if(pETUDSink)
{
pETUDSink->Start();
} however it always returns an error saying that the class is not registered. I can't use MFC to call the relevant .rgs file and am completely stuck on how to get this to work otherwise.
Is there a given format to doing this that I am unaware of and has anyone had experience in using the ETUDriver (or is able to get it working in C++ without use of MFC)?
Thank you for any help you can provide on this subject :)
I am not familiar with the specific DLL in question, but it sounds like you did not register the DLL on the target machine. You can do this by running regsvr32.exe or by calling the DLL's exported DllRegisterServer function or by using side-by-side assemblies. You need to do register the DLL on each machine that needs to leverage the COM functionality within it, so when you distribute your application, make sure that your installer registers the DLL if you go the regsvr32.exe route.
You can use the #import directive in Microsoft Visual C++ to load the information contained within the DLL without using a header file or rewriting it yourself based on documentation.
I disassemled a game's DLL and want to insert some code.
I need asm code to call another DLL in the current directory(I'm on Windows).
The background is, that I want to be able to execute custom code in my DLL,
but I can't load the DLL. So my idea was to load the DLL via modified game DLL.
There may be a function in the game which gives me the current directory path the DLL's are but I think I won't find it.
The calls you are looking for are LoadLibrary, which will search in a selection of places including the current directory for the DLL and then load it, then GetProcAddress.
If the DLL makes any other Win32 calls it is probably already linked against kernel32.dll, so that's all you need to do.
It is arguable as to whether modifying the DLL or using DLL injection is faster in terms of how long it takes to write the code since you're going to have to reverse engineer anyway, however, one advantage of pure DLL injection is that all existing code remains unmodified in terms of the installation, making these modifications easier to undo should the user wish to "unpatch" whatever you are doing.
Microsoft Detours comes with setdll.exe and withdll.exe, those utilities will let you start an exe with a custom dll file.