This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- InstallShield
- :
- InstallShield Forum
- :
- Re: Calling a DLL from Installation via Custom Action
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Nov 09, 2009
01:58 PM
Calling a DLL from Installation via Custom Action
Hello Again,
I'm trying to test calling a dll that verifies some user entered codes saved in Windows Installer Properties.
I've tried various options in creating the custom action, but nothing is working - can't find entry, 1723 errors, etc. I didn't log the install, but can do so.
The dll is a C++ library, I believe and basically does the following in the CompanyCheckEntries(MSIHANDLE msi)...
Checks the length of an entry stored in and grabbed from a PROPERTY and compares two other entries, also stored and grabbed from properties.
Here is some of the code...
[CODE]DLLEXPORT UINT _stdcall CompanyCheckEntries(MSIHANDLE msi)
{
CString csSerial, csAuth, csSeats;
int iRet = 0;
int iNumSeats = 0;
char buff[256];
DWORD dwSize = sizeof(buff);
int iWinErr = MsiGetProperty(msi, APP_SERIAL_NUMBER, buff, &dwSize);
if(iWinErr == ERROR_SUCCESS
&& dwSize == APP_SERIALNUMLEN ) //make sure its 8 characters
{
buff[APP_SERIALNUMLEN] = 0;
NfmTrim(buff); //comes in space padded - make sure its 8 characters
if(strlen(buff) == APP_SERIALNUMLEN)
{
csSerial = buff;
dwSize = sizeof(buff);
iWinErr = MsiGetProperty(msi, APP_AUTHORIZATION_CODE, buff, &dwSize);
}
}
if(iWinErr == ERROR_SUCCESS)
{
csAuth = buff;
dwSize = sizeof(buff);
iWinErr = MsiGetProperty(msi, APP_NUMBER_OF_SEATS, buff, &dwSize);
}
if(iWinErr == ERROR_SUCCESS)
{
csSeats = buff;
dwSize = sizeof(buff);
iNumSeats = atoi(buff);
}
int iSetValid = -1;
if(iNumSeats > 0)
{
iRet = ERROR_SUCCESS;
Company_SIGNATURE adSig, encSig;
memset(&adSig,0,sizeof(adSig));
memset(&encSig,0,sizeof(encSig));
strcpy(adSig.signature,STD_SIGNATURE);
NfmSafeCopy(adSig.serial, csSerial, AD_SERLEN );
NfmSafeCopy(adSig.authcode, csAuth, AD_AUTHLEN );
NfmSafeCopy(adSig.machine, "0", AD_MACHLEN);
NfmSafeCopy(adSig.socket, "0", AD_SOCKLEN);
int iSeats = EncryptSignature( &adSig, &encSig );
MsiSetProperty(msi,APP_VALID, iSeats == iNumSeats ? "1" : "0");
}
return iRet;
}[/CODE]
With all of this, what action should I use - Standard .dll or Windows Installer .dll? Walking through the CA Wizard, how would I set this up?
Basically what happens then is a dialog is shown indicating invalid codes if APP_VALID = "0" when the Dialog's Next button is pressed. Otherwise (="1") the interface continues.
Any help with this would be greatly appreciated!
I'm trying to test calling a dll that verifies some user entered codes saved in Windows Installer Properties.
I've tried various options in creating the custom action, but nothing is working - can't find entry, 1723 errors, etc. I didn't log the install, but can do so.
The dll is a C++ library, I believe and basically does the following in the CompanyCheckEntries(MSIHANDLE msi)...
Checks the length of an entry stored in and grabbed from a PROPERTY and compares two other entries, also stored and grabbed from properties.
Here is some of the code...
[CODE]DLLEXPORT UINT _stdcall CompanyCheckEntries(MSIHANDLE msi)
{
CString csSerial, csAuth, csSeats;
int iRet = 0;
int iNumSeats = 0;
char buff[256];
DWORD dwSize = sizeof(buff);
int iWinErr = MsiGetProperty(msi, APP_SERIAL_NUMBER, buff, &dwSize);
if(iWinErr == ERROR_SUCCESS
&& dwSize == APP_SERIALNUMLEN ) //make sure its 8 characters
{
buff[APP_SERIALNUMLEN] = 0;
NfmTrim(buff); //comes in space padded - make sure its 8 characters
if(strlen(buff) == APP_SERIALNUMLEN)
{
csSerial = buff;
dwSize = sizeof(buff);
iWinErr = MsiGetProperty(msi, APP_AUTHORIZATION_CODE, buff, &dwSize);
}
}
if(iWinErr == ERROR_SUCCESS)
{
csAuth = buff;
dwSize = sizeof(buff);
iWinErr = MsiGetProperty(msi, APP_NUMBER_OF_SEATS, buff, &dwSize);
}
if(iWinErr == ERROR_SUCCESS)
{
csSeats = buff;
dwSize = sizeof(buff);
iNumSeats = atoi(buff);
}
int iSetValid = -1;
if(iNumSeats > 0)
{
iRet = ERROR_SUCCESS;
Company_SIGNATURE adSig, encSig;
memset(&adSig,0,sizeof(adSig));
memset(&encSig,0,sizeof(encSig));
strcpy(adSig.signature,STD_SIGNATURE);
NfmSafeCopy(adSig.serial, csSerial, AD_SERLEN );
NfmSafeCopy(adSig.authcode, csAuth, AD_AUTHLEN );
NfmSafeCopy(adSig.machine, "0", AD_MACHLEN);
NfmSafeCopy(adSig.socket, "0", AD_SOCKLEN);
int iSeats = EncryptSignature( &adSig, &encSig );
MsiSetProperty(msi,APP_VALID, iSeats == iNumSeats ? "1" : "0");
}
return iRet;
}[/CODE]
With all of this, what action should I use - Standard .dll or Windows Installer .dll? Walking through the CA Wizard, how would I set this up?
Basically what happens then is a dialog is shown indicating invalid codes if APP_VALID = "0" when the Dialog's Next button is pressed. Otherwise (="1") the interface continues.
Any help with this would be greatly appreciated!
(2) Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Nov 09, 2009
06:10 PM
If the DLL functions have the signature
Since these are called in the user interface, you can define the action to use immediate mode. Since you're triggering the action with a button click, the dialog should use a DoAction control event to trigger the action, instead of scheduling the action in the sequences.
If you use Dependency Walker or dumpbin, are the exported function names what you expect? If not, you might want to build the DLL using a .def file, which suppresses C++ name decoration for the exported functions.
(It's not central to the issue, but it appears the function will never return anything but the value ERROR_SUCCESS, which is 0, even though there's logic in there to set the return value.)
UINT __stdcall SomethingSomething(HWND hInstall)you'll want to use a Windows Installer (MSI) DLL action and not a "standard DLL" action.
Since these are called in the user interface, you can define the action to use immediate mode. Since you're triggering the action with a button click, the dialog should use a DoAction control event to trigger the action, instead of scheduling the action in the sequences.
If you use Dependency Walker or dumpbin, are the exported function names what you expect? If not, you might want to build the DLL using a .def file, which suppresses C++ name decoration for the exported functions.
(It's not central to the issue, but it appears the function will never return anything but the value ERROR_SUCCESS, which is 0, even though there's logic in there to set the return value.)
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Nov 10, 2009
07:17 AM
The code does work in our current installations built with the product we are looking to migrate from.
I'll keep hacking away at it.
I guess I'll have to look into the naming issue a bit.
I know how to set up the action from the dialog, but I was wondering what setting the actual Custom Action needed with regard to the dll itself (function called, which I will look into the naming, etc).
Oh, thanks for the Dependency Walker idea - it gave me _CompanyCheckEntries@4 as the Function Name.
I'll keep hacking away at it.
I guess I'll have to look into the naming issue a bit.
I know how to set up the action from the dialog, but I was wondering what setting the actual Custom Action needed with regard to the dll itself (function called, which I will look into the naming, etc).
Oh, thanks for the Dependency Walker idea - it gave me _CompanyCheckEntries@4 as the Function Name.
![](/skins/images/CC38E504FC9E1309DC48ACFEB4925670/responsive_peak/images/icon_anonymous_message.png)