cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
cute_martian
Level 3

Conversion to InstallShield 2008 broke install

Hi there,

I am in the process of converting my MSI Basic installation project from InstallShield 10.5 to InstallShield 2008. The conversion process itself did not produce any errors, but then when I tried running my installation package, the very first deferred InstallScript custom action failed.

The MSI log entries are not very helpful, please see attached.

MSI (s) (C4:C8) [16:51:24:383]: Executing op: ActionStart(Name=RemoveVMMCPUserSettings,,)
Action 16:51:24: RemoveVMMCPUserSettings.
MSI (s) (C4:C8) [16:51:24:398]: Executing op: CustomActionSchedule(Action=RemoveVMMCPUserSettings,ActionType=1025,Source=BinaryData,Target=f35,CustomActionData=C:\DOCUME~1\debown\LOCALS~1\Temp\{507159AC-8AAB-4EB7-8DC9-AA2A552D01B5})
MSI (s) (C4:9C) [16:51:25:320]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSI1085.tmp, Entrypoint: f35
InstallShield 16:51:25: Running InstallScript function f35
InstallShield 16:51:25: Using temp folder C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}
InstallShield 16:51:25: Installing engine...
InstallShield 16:51:25: Using product language 1033
InstallShield 16:51:25: Extracting support file setup.inx to C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}\setup.inx
InstallShield 16:51:25: Opening stream of file C:\WINDOWS\Installer\MSI1085.tmp
InstallShield 16:51:25: Extracting support file ISRT.dll to C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}\ISRT.dll
InstallShield 16:51:26: Extracting support file IsConfig.ini to C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}\IsConfig.ini
InstallShield 16:51:26: Extracting support file _isres1033.dll to C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}\_isres.dll
InstallShield 16:51:26: Extracting support file String1033.txt to C:\DOCUME~1\debown\LOCALS~1\Temp\{1AD4CD13-6510-4CAA-987E-D8BC6CFA9389}\String1033.txt
InstallShield 16:51:26: Skipping optional support file _isuser1033.dll
InstallShield 16:51:26: Setting script cmdline...
InstallShield 16:51:26: ProductCode is {507159AC-8AAB-4EB7-8DC9-AA2A552D01B5}
InstallShield 16:51:26: Initializing Engine
InstallShield 16:51:27: Done Initializing...
InstallShield 16:51:27: Registering Msi Server...
InstallShield 16:51:27: Invoking script function RemoveVMMCPUserSettingsCA
InstallShield 16:51:35: CallScriptFunctionFromMsiCA() ends
Action ended 16:51:35: InstallFinalize. Return value 3.


I read on Helpnet and on this forum that I need to use CustomActionData to access SUPPORTDIR property in my custom action. When I tried implementing this change into my custom action, it did not make any difference. The custom action that I modified to include this change is still failing. This custom action is an installScript custom action of type 66560 (deferred).

Here is what I tried:
1. Created a Set-Property immediate execute custom action that sets:
RemoveVMMCPUserSettings to [SUPPORTDIR].
And then modified my InstallScript code to call MsiGetProperty(hInstall, "CustomActionData", szSupportDirPath, nBuffer);
The same error occurrs and then my install rolls back.
2. Changed my deferred custom action to execute in System Context - did not make any difference. Same problem occurrs as before.
3. Followed the instructions line by line in the Helpnet article to create a new Set-Property custom GetSUPPORTDIR action to pass SUPPORTDIR to a deferred InstallScript custom action DisplaySupportDir.
http://helpnet.acresso.com/Robo/BIN/Robo.dll?tpc=%2Frobo%2Fprojects%2Finstallshieldlivinghelp%2FISLivingHelpMain2.htm&mgr=agm&wnd=InstallShieldLivingHelp%7CMain&agt=wsm&ctxid=showthread.php
The message boxes display what seems to be reasonable values, however, when I added a call to StreamFileFromBinary and passes the value that is stored in CustomActionData for SUPPORTDIR, the StreamFileFromBinary failed with error -1. Not sure at all why this is happening.
4. Tried streaming different file from the Binary table, did not make a difference, still getting return code -1 when calling StreamFileFromBinary.
5. Don't think the problem is with the files that I am trying to stream from the Binary table, since the same file works fine when streamed from the Binary table during my immediate execution custom actions.
6. Tried streaming a simple text file (thinking maybe the problem is with the DLL dependencies or some other thing like that), still the same problem persists.
7. Tried running ICE validation, but that didn't help at all.

Here are the source for the custom actions that I tried:
export prototype RemoveVMMCPUserSettingsCA(HWND);
export prototype DisplaySupportDir(HWND);

function DisplaySupportDir(hInstall)
STRING supportDirPath, szBinaryKey, szFileName;
NUMBER supportDirPathBuffer, nResult;
begin

supportDirPathBuffer = _MAX_PATH;
if (MsiGetProperty(hInstall, "CustomActionData", supportDirPath, supportDirPathBuffer) == ERROR_SUCCESS) then
SprintfBox(INFORMATION, "Deferred Execution", "The value of SUPPORTDIR is %s", supportDirPath);
SprintfBox(INFORMATION, "Deferred Execution", "The value of InstallScript's SUPPORTDIR is %s", SUPPORTDIR);
endif;

szFileName = supportDirPath ^ SUPPORT_DLL;
MessageBox (szFileName, INFORMATION);
nResult = StreamFileFromBinary(hInstall, "VMInst2_Binary", szFileName);
if (nResult == 0) then
SprintfBox(INFORMATION, "Deferred Execution", "Non-InstallScript SUPPORTDIR result is %d", nResult);
endif;
if (nResult == -1) then
SprintfBox(INFORMATION, "Deferred Execution", "Non-InstallScript SUPPORTDIR result is %d", nResult);
endif;

szFileName = SUPPORTDIR ^ SUPPORT_DLL;
MessageBox (szFileName, INFORMATION);
nResult = StreamFileFromBinary(hInstall, "VMInst2_Binary", szFileName);
if (nResult == 0) then
SprintfBox(INFORMATION, "Deferred Execution", "Non-InstallScript SUPPORTDIR result is %d", nResult);
endif;
if (nResult == -1) then
SprintfBox(INFORMATION, "Deferred Execution", "Non-InstallScript SUPPORTDIR result is %d", nResult);
endif;

end;


function RemoveVMMCPUserSettingsCA(hInstall)
STRING szBinaryKey, szFileName, szSubKey, szSupportDirPath;
NUMBER nResult, nBuffer;

begin
szBinaryKey = "VMInst2_Binary";
nBuffer = _MAX_PATH;
MsiGetProperty(hInstall, "CustomActionData", szSupportDirPath, nBuffer);
//szFileName = SUPPORTDIR ^ SUPPORT_DLL;
//MessageBox(szFileName, INFORMATION);
//nResult = StreamFileFromBinary(hInstall,szBinaryKey,szFileName);
szFileName = szSupportDirPath ^ SUPPORT_DLL;
nResult = StreamFileFromBinary(hInstall,szBinaryKey,szFileName);
if (nResult == 0) then
MessageBox("Success", INFORMATION);
endif;
if (nResult == -1) then
MessageBox(szFileName, INFORMATION);
endif;
UseDLL(szFileName);
Trace("Script.RemoveVMMCPUserSettingsCA", "Entered");
UnUseDLL(szFileName);

//Determine if the VMMCP UserSettings key exists.
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
szSubKey = VMMCP_USER_SETTINGS;
nResult = RegDBKeyExist(szSubKey);
if (nResult == 1) then
// Delete it
nResult = RegDBDeleteKey(szSubKey);
endif;
end;


Attached are the source files of my converted project, the MSI log file and some screen captures used for debugging.


Any help would be greatly appreciated, since I think I am stuck at this point.

Natalia
Labels (1)
0 Kudos
(4) Replies
MichaelU
Level 12 Flexeran
Level 12 Flexeran

From your description, I believe the main problem is the call to StreamFileFromBinary. This requires access to the MSI database (internally it's implemented with API calls like MsiGetActiveDatabase, and MsiDatabaseOpenView) which is not available during deferred mode (you can see they're not listed on http://msdn2.microsoft.com/en-us/library/aa370543(VS.85).aspx).

One approach that could work is instead of passing SUPPORTDIR to the deferred action, use StreamFileFromBinary in the immediate action and pass its location to the deferred action. Obviously if you need more than one, this can get a little cumbersome, but there are samples around for sending and parsing multiple values via CustomActionData.
0 Kudos
cute_martian
Level 3

Hi MichaelU,

Thank you for your reply. Could you elaborate on your suggestion to "use StreamFileFromBinary in the immediate action and pass its location to the deferred action"? I am not sure I follow what you are suggesting here. Thanks! If you are asking to pass the SUPPORTDIR value that I am using in my immediate custom actions, then these locations are dynamic, so every call generates a new value for SUPPORTDIR location.

Also, the MSDN link that you sent is broken.

Just out of curiosity, to me it seems that being able to access the MSI database during the deferred custom action should be a reasonable thing to do, considering that I was able to do this in previous version of InstallShield product. How come all of the sudden this functionality is broken?

Thanks,
Natalia

P.S. Do you think I should file an incident report to resolve this issue? Thanks.
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

I'm saying pass the path of the extracted file was (or of the directory where it and others were) extracted. You're correct that each custom action now gets its own (InstallScript variable) SUPPORTDIR, but the installation as a whole only gets one (MSI Property) SUPPORTDIR. The latter could be passed through CustomActionData and retrieved through MsiGetProperty as the directory where the file is extracted.

My previous posting of the link appears to have an extra parenthesis on it - the correct one is: http://msdn2.microsoft.com/en-us/library/aa370543(VS.85).aspx

This behavioral change is due to us no longer using an out-of-process connection that should never have been used, and was fixed as part of the engine refactoring in IS12. You can file an incident if you want, but the end result will be the same general suggestion: the file must be available on the filesystem when the deferred action gets to it. Whether this is from an immediate custom action that uses StreamFileFromBinary, or from the automatic support of the support files (and passing SUPPORTDIR via CustomActionData), you will no longer be able to access the MSI database during the deferred action.
0 Kudos
Christopher_Pai
Level 16

cute martian wrote:

Just out of curiosity, to me it seems that being able to access the MSI database during the deferred custom action should be a reasonable thing to do, considering that I was able to do this in previous version of InstallShield product. How come all of the sudden this functionality is broken?


It's the opposite. It was an unreasonable thing that InstallShield's InstallScript engine allowed to happen. If you were writing C++ or VBScript you would have never been able to gain access to the stream from the immeadiate because of execution context issues baked into MSI.

You need to write an Immeadiate CA that queries the DB and extracts the stream and generates the CustomActionData property to pass the location of the file to the Deferred CA. Then in the deferred CA you can cleanup the temp file.

Here is an article with a link to some sample code that describes the pattern a bit ( minus the stream a file part )

http://blog.deploymentengineering.com/2006/08/customactiondata-for-installscript-12.html
0 Kudos