cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
manomatt
Level 8

Functionality which working in 2012Spring is not working in 2014

Hi,

I am Not able to Increment ProgressBar from OnLaunchAppAndWaitCallback(). Earlier this was working in InstallShield 2012Spring after migration to InstallShield 2014 it stopped working?

Is there any issue associated with the migration?





thanks in advance.
Labels (1)
0 Kudos
(7) Replies
manomatt
Level 8

Hi,


I installed InstallShield 2014 SP1 and tried the same... the issue is still happening.

MsiProcessMessage(hMSI , INSTALLMESSAGE_PROGRESS, hRecord); is NOT at all working
0 Kudos
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

We have been able to verify that reporting progress through MsiProcessMessage (either in an MSI DLL or InstallScript custom action) functions correctly. There have been no changes to InstallScript's MSI function wrappers that would have affected this. Windows Installer itself and its APIs will only change according to the Windows version an installation is running on.

If you are using a Basic MSI project with InstallScript actions to control the progress bar, how many total ticks are you adding to the progress bar through MsiProcessMessage (assuming the code you are using is not resetting the progress bar)? This will have an impact of how much progress is seen on the progress bar through MsiProcessMessage calls. For example, with an MSI package that does not contain much information, say the total size of the MSI package itself is ~5MB. If a custom action adds 100000 ticks to the total progress of the installation (as is outlined in the Adding Custom Actions to the ProgressBar article on MSDN), then the custom action only accounts for about 2% of the overall movement of the progress bar. A progress increment of 10000 ticks will then only add about 0.2% forward progress to the progress bar. For the progress bar's typical size, this movement may or may not be visible. The larger the MSI package gets the less visible impact a specific custom action has on the progress bar will be seen.

In this case, the custom action needs to specify a larger total tick value to remain visible to the progress of the installation. Otherwise, the custom action's percentage of the total progress report (as a function of the installation size) will decrease as the rest of the MSI package increases in size. Generally speaking, this would be expected behavior since the custom action may or may not have increased the amount of data it itself reporting.
0 Kudos
manomatt
Level 8

I appreciate the information that you had provided me,but in my case I am resetting the ProgressBar. Then adding my custom ticks say 200 that would give me ample increment in the progressbar. This has been properly working in the previous versions. I don't think its the problem with the MSI. Can you verify this.

joshstechnij wrote:
We have been able to verify that reporting progress through MsiProcessMessage (either in an MSI DLL or InstallScript custom action) functions correctly. There have been no changes to InstallScript's MSI function wrappers that would have affected this. Windows Installer itself and its APIs will only change according to the Windows version an installation is running on.

If you are using a Basic MSI project with InstallScript actions to control the progress bar, how many total ticks are you adding to the progress bar through MsiProcessMessage (assuming the code you are using is not resetting the progress bar)? This will have an impact of how much progress is seen on the progress bar through MsiProcessMessage calls. For example, with an MSI package that does not contain much information, say the total size of the MSI package itself is ~5MB. If a custom action adds 100000 ticks to the total progress of the installation (as is outlined in the Adding Custom Actions to the ProgressBar article on MSDN), then the custom action only accounts for about 2% of the overall movement of the progress bar. A progress increment of 10000 ticks will then only add about 0.2% forward progress to the progress bar. For the progress bar's typical size, this movement may or may not be visible. The larger the MSI package gets the less visible impact a specific custom action has on the progress bar will be seen.

In this case, the custom action needs to specify a larger total tick value to remain visible to the progress of the installation. Otherwise, the custom action's percentage of the total progress report (as a function of the installation size) will decrease as the rest of the MSI package increases in size. Generally speaking, this would be expected behavior since the custom action may or may not have increased the amount of data it itself reporting.
0 Kudos
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

The following InstallScript custom action code, sequenced between InstallInitialize and InstallFinalize in the install execute sequence (with an in-script execution setting of deferred), is able to control the progress bar as expected when built with InstallShield 2014 or 2014 SP1.


export prototype NUMBER DoProgress(HWND);

function DoProgress(hMSI)
HWND hRecord;
NUMBER nProcessResult, nReturn, i;
begin
nReturn = ERROR_SUCCESS;

hRecord = MsiCreateRecord(4);

//
// Reset the progress bar to 100 total ticks.
//
MsiRecordSetInteger(hRecord, 1, 0);
MsiRecordSetInteger(hRecord, 2, 100);
MsiRecordSetInteger(hRecord, 3, 0);
MsiRecordSetInteger(hRecord, 4, 0);
nProcessResult = MsiProcessMessage(hMSI, INSTALLMESSAGE_PROGRESS, hRecord);
if(nProcessResult == IDCANCEL) then
nReturn = ERROR_INSTALL_USEREXIT;
goto dp_end;
endif;

MsiCloseHandle(hRecord);

hRecord = MsiCreateRecord(3);

MsiRecordSetString(hRecord, 1, "This is IS custom action");
MsiRecordSetString(hRecord, 2, "Running this action...");
MsiRecordSetString(hRecord, 3, "");
nProcessResult = MsiProcessMessage(hMSI, INSTALLMESSAGE_ACTIONSTART, hRecord);
if(nProcessResult == IDCANCEL) then
nReturn = ERROR_INSTALL_USEREXIT;
goto dp_end;
endif;

MsiCloseHandle(hRecord);

for i = 0 to 100
Sleep(125);
hRecord = MsiCreateRecord(3);

//
// Send one progress tick.
//
MsiRecordSetInteger(hRecord, 1, 2);
MsiRecordSetInteger(hRecord, 2, 1);
MsiRecordSetInteger(hRecord, 3, 0);
nProcessResult = MsiProcessMessage(hMSI, INSTALLMESSAGE_PROGRESS, hRecord);
if(nProcessResult == IDCANCEL) then
nReturn = ERROR_INSTALL_USEREXIT;
goto dp_end;
endif;

MsiCloseHandle(hRecord);
endfor;

dp_end:
MsiCloseHandle(hRecord);
return nReturn;
end;


All the function calls in this test code go directly into MSI API calls (MsiCreateRecord, MsiRecordSetInteger, MsiProcessMessage, etc.). InstallScript does not perform any sort of manipulations on the data passed to these functions. In addition, nothing has changed in the support provided by InstallScript for these functions in IS 2014.

To verify that calls to MSI APIs are reaching Windows Installer correctly, you can view MSI debug messages by enabling the MSI debug policy in the registry and use a debug output viewer such as DebugView from Sysinternals. When running your custom action, calls to MSI record functions or MsiProcessMessage are logged by MSI with the parameter values passed to the functions. This can be used to verify that the calls are reaching Windows Installer correctly.
0 Kudos
manomatt
Level 8

Hello Josh

First of all thanks a lot for that reply.... I had tried the piece of code that you had provided.

When i sequenced is as per your instructions and called this customaction, it was working fine. I even tried to call this as a immediate CA after installFinalize and it was working fine.

But the issue that i am facing is a bit different , what i was trying to say was when this function is called from "OnLaunchAppAndWaitCallback()" that is not getting any interaction with the UI. I am using something like this:

function TestMessage(hMSI,szProgram,szCmdline)
begin
LaunchAppAndWait(szProgram,szCmdline,LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN | LAAW_OPTION_USE_CALLBACK);
end;


and

function NUMBER OnLaunchAppAndWaitCallback()
HWND hMSI;
STRING szMsg;
NUMBER nReturn;
OBJECT hRecord;
begin
DoProgress(hMSI);
end;


Can you please try this and see?

I have provided the debug log :

[CODE]00002888 5:21:14 PM [38440] MSI (s) (28!D8) [17:21:14:837]: Creating MSIHANDLE (404) of type 790531 for thread 38104
00002889 5:21:14 PM [38440]
00002890 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:837]: Passing to service: MsiRecordSetInteger(404, 1, 0)
00002891 5:21:14 PM [36888]
00002892 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:838]: Passing to service: MsiRecordSetInteger(404, 2, 100)
00002893 5:21:14 PM [36888]
00002894 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:838]: Passing to service: MsiRecordSetInteger(404, 3, 0)
00002895 5:21:14 PM [36888]
00002896 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:838]: Passing to service: MsiRecordSetInteger(404, 4, 0)
00002897 5:21:14 PM [36888]
00002898 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:838]: Passing to service: MsiProcessMessage(0, 167772160, 404)
00002899 5:21:14 PM [36888]
00002900 5:21:14 PM [36888] MSI (a) (18:D8) [17:21:14:838]: Passing to service: MsiCloseHandle(404)[/CODE]

It seem to me that the MsiProcessMessage handle is going to 0 when the call is being made from the OnLaunchAppAndWaitCallback(). May be you can provide me more light in this situation.
0 Kudos
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

The DoProgress call in the posted OnLaunchAppAndWaitCallback code is being passed an unset HWND variable (hMSI) that is local to the OnLaunchAppAndWaitCallback function. In InstallScript an HWND variable is essentially an integer, and all integer variables are initialized by the script engine to zero.

Is there other code not in the posted code that initializes hMSI? In order for the DoProgress function to work correctly when calling MsiProcessMessage, a valid handle needs to be passed. Either the handle can be saved in a global variable in the custom action entry point, or the pseudo variable ISMSI_HANDLE could be used in the call to DoProgress to provide the installation handle.

Please note that unless there is code missing from the posted OnLaunchAppAndWaitCallback code here that would have set hMSI to a valid handle, no functionality between IS 2014 and older versions of InstallShield has changed that would result in the hMSI local variable in OnLaunchAppAndWaitCallback being a valid installation handle.
0 Kudos
manomatt
Level 8

There is no extra code to set the MSI handle from the OnLaunchAppAndWaitCallback(). I had tried the same code in InstallShield 2012Spring and it was working properly. When this same code was used in InstallShield 2014 this started to behave differently.

As you have rightly mentioned that the msi handle needs to be set in OnLaunchAppAndWaitCallback() otherwise the script engine will initialize it to 0. But why is that initialization NOT happening in 2012Spring? How is that working there? Please share some light on this scenario.


I tried having a global variable and using that to set the handle value in the custom action entry point in IS 2014, it started to work. I had tried with setting a pseudo variable ISMSI_HANDLE that also seem to work. Thank you so much for that suggestion.


PS: Previously I was using hRecord as OBJECT type and for making it to work in 2014 i changed it to HWND.
0 Kudos