I'd wish to get the .msi uninstall process add some values under this regkey that's being removed:


to simulate uninstall didn't happened to avoid undesired effect on a dependent app that is not actually needing it. I'd wish to do it that way or similar one to be able to trigger uninstall from the entry in ARP, to avoid confusion among users.

And I don't know if this is possible. I'm trying with a previously tested .vbs from custom action type 38 (.vbs in one line ... : ... : ...) with no luck. I'm beginning to think I'm wasting my time.

Any ideas?
Thx in advance.
0 Comments   [ - ] Hide Comments


Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
Answer this question or Comment on this question for clarity


I'm not understanding what you're trying to achieve.
Don't mess with the Windows Installer metadata "hive".
Answered 02/12/2009 by: AngelD
Red Belt

Please log in to comment
I'd want to know at what moment of the uninstall process is this metadata removed from the registry, and if it can be rewritten to registry in some way from the same process before it exits, or scheduled the execution of a script to be run immediately after process finish, subverting this part of the uninstall process, to do everything in a single step from ARP.

I've tried to trigger the uninstall with a script to modify the registry after uninstall changing the UninstallString with no luck. And all my trials modifying the database with a transform injecting a custom action have failed. I'm exploring commit custom actions with an .vbs

Is it possible?

Thx for your help.
Answered 02/12/2009 by: strel
Senior Yellow Belt

Please log in to comment
May I ask why you want this?

I guess it could be possible however, I wouldn't recommend it.
You would need to manually execute the (standard) actions that writes the metadata or make sure the actions removing the metadata are not executed during uninstall
Answered 02/13/2009 by: AngelD
Red Belt

Please log in to comment
It's because I want to have freedom to install and uninstall the unnecessary piece of software without affecting other applications.

The thing is that the values I want to add under this metadata regkeys are not included in the packet, because it corresponds to a non patcheable update I wanted to avoid too.

So I suppose I should search the removing standard action just before InstallFinalize action in InstallExecuteSequence table, and I'll need deferred custom action(s), all this because of the elevated privileges needed to write the registy. Is this correct?

About the .vbs I read in other post it's better not to embed it. Is this meaning not to use vbs code from custom action type 38?

Answered 02/13/2009 by: strel
Senior Yellow Belt

Please log in to comment
I've found the solution:

As I couldn't find the way to disable the install/uninstall process metadata writting onto the registry nor the way of writting my own metadata before install/uninstall process ends, what I did is to use the return processing options of the custom action to set it msidbCustomActionTypeContinue + msidbCustomActionTypeAsync (continue on return and asynchronous), so that the custom action can be executed after the install/uninstall process ends.

This way the custom action has to be EXE type so I choose type 2 (exe from bynary table stream) and insert an .exe obtained from an .vbs file with ExeScript (http://www.hide-folder.com/overview/hf_7.html) that checks if the install/uninstall process has ended, and then write my metadata to registry.
Dim blnRunning, colProcesses
blnRunning = True
Do Until Not blnRunning
Set colProcesses = GetObject( "winmgmts:{impersonationLevel=impersonate}" ).ExecQuery( "Select * From Win32_Process Where Name = '" & "msiexec.exe" & "'" )
WScript.Sleep 100
If colProcesses.Count = 0 Then
blnRunning = False
End If
Set WshShell = CreateObject( "WScript.Shell" )
WshShell.RegWrite "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\15B3183CD7C6F2D8E8F0DCC03A48AD88\Value1", WshShell.ExpandEnvironmentStrings( "%SYSTEMROOT%\Installer\1234mxj.msi" ), "REG_SZ"
WshShell.RegWrite "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\15B3183CD7C6F2D8E8F0DCC03A48AD88\Patches\DAE54917E4E118470E9485F10410F3FB\Value2", "1", "REG_DWORD"
Set WshShell = Nothing

Then I inserted this custom action into InstallExecuteSequence table between InstallInitialize and InstallFinalize standard actions.
And voila!
Enjoy. =P
Answered 02/26/2009 by: strel
Senior Yellow Belt

Please log in to comment
What you mean by 'This way the custom action has to be EXE type'?

If I were you I'd:

- add a LOT of error-trapping to your code. It assumes that everything is going to work first time, every time. ALWAYS program defensively and assume NOTHING is going to work.
- add another loop into your process-watching loop so that it only waits for time 'x' before assuming that the process isn't going to end. Otherwise, if your package gets run after any other, MSIExec.EXE will quite likely still be running (the engine sometimes keeps the server instance running, long after the install which started it has completed) meaning that you script will be stuck in an endless loop. That sort of behaviour isn't too popular with users...
Answered 02/26/2009 by: VBScab
Red Belt

Please log in to comment
I mean that using this Return Processing options above there's limits described in Windows Installer SDK help file:
"An asynchronous execution that does not wait for completion.
Execution continues after Windows Installer terminates.
This option can only be used with the EXE type custom actions—that is, executable files.
All other types of custom actions can be asynchronous only within the install session, and must end for the installation to terminate.
This option cannot be used with Concurrent Installations."
I had observed yet msiexec.exe still running after my install/uninstall process ends, in fact I was using:...If colProcesses.Count = 1 Then...
But you're right it could get in an endless loop, so it can be added code to stop or wait any msiexec.exe processes running before starting, and to avoid not run concurrently with another msiexec.exe process. But this is not my intention, I'm not beeing paid for this, so my users will have to follow my yellow brick path. But up to anyone who uses this idea.

Anyway luckyly I can make the script watch another singular process related to this install/uninstall to determine when to write the metadata registry keys, avoiding that problems easyly.
Thx for you advices.
Answered 02/26/2009 by: strel
Senior Yellow Belt

Please log in to comment
If you're going that path which I wouldn't recommend ;) I would pass the msiexec processid and check when that process has ended.
ProcessId = Session.Property("CLIENTPROCESSID")

The select query would then look like:

"Select * From Win32_Process Where ProcessId = '" & ProcessId & "'"

I've used a similar wmi script at http://www.appdeploy.com/messageboards/fb.asp?m=44926
You need to tweak if for your purpose.
Answered 02/26/2009 by: AngelD
Red Belt

Please log in to comment