Nested Parameters?

I’m trying to create a general MSI uninstaller that would prompt for a display name and uninstall based on provided information. I found a couple examples that people don’t seem to have gotten to work. Mine works in all things except the actual parameter substitution. It seems like it is some kind of double relevance error, but no combination of brackets or braces seems to have the desired effect. My action script is below (and works fine in QnA if I use a plain name instead of the parameter. Calling a parameter within a relevance expression itself not possible?

action parameter query “name” with description “Please enter the Program Name”

waithidden msiexec.exe /x{name of key whose (value “DisplayName” of it as string as lowercase contains (parameter “app” of action as string) and name of it starts with “{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart

So am I missing something?

My guess is you’re not escaping the “{” to escape this character you’ll need to use “{{”

Nah. That was one of the first things I tried:

Command succeeded action parameter query “name” with description “Please enter the Program Name” (action:238038)

Command failed (Relevance substitution failed) waithidden msiexec.exe /x{{name of key whose (value “DisplayName” of it as string as lowercase contains (parameter “name” of action as string) and name of it starts with “{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart (action:238038)

You’re looking at the wrong “{” :slight_smile:

waithidden msiexec.exe /x {name of key whose (value "DisplayName" of it as string as lowercase contains (parameter "app" of action as string) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /quiet /norestart

ah. Ok. A little better it seems, but not the task is hanging somehow.

Command started - waithidden msiexec.exe /x{name of key whose (value “DisplayName” of it as string as lowercase contains (parameter “name” of action as string) and name of it starts with “{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart (action:238045)

While this works and doesn’t hang:

waithidden msiexec.exe /x{name of key whose (value “DisplayName” of it as string as lowercase contains “snagit” and name of it starts with “{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart

So still choking on the parameter somehow…

Well i’d probably change /quiet to /qn it’s likely that it’s failing for some reason and msiexec is hanging.

It also looks like you’re converting the value "displayname" to lowercase but not your parameter "name" of action.

To assist with troubleshooting you could also put this into a batch file.

delete run.bat
createfile until _end_

msiexec.exe /x{name of key whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string as lowercase) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /quiet /norestart

_end_

move __createfile run.bat

waithidden run.bat

This will create a run.bat in the client site folder that will allow you to more easily test the resultant command

Doesn’t look like any of the relevance is getting parsed in the batch file. I might need to let it incubate.

Can you provide your exact actionscript?

This is the one to create the batch file:
action parameter query “name” with description “Please enter the Program Name”

delete run.bat
createfile until _end_

waithidden msiexec.exe /x{{name of key whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /qn

_end_

move __createfile run.bat

waithidden run.bat

and this was the original:

action parameter query "name" with description "Please enter the Program Name"

waithidden msiexec.exe /x{{name of key whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /qn

Pasting stripped the underscores out of the batch file but they’re there.

It looks like you’re missing your action parameter query from the new one.

It’s super important to always share your exact actionscript that you are running – in this case you shouldn’t be escaping the first “{” just the second one like how I did it in my example.

action parameter query "name" with description "Please enter the Program Name"

delete run.bat
createfile until _end_

msiexec.exe /x {name of key whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string as lowercase) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /quiet /norestart

_end_

move __createfile run.bat

waithidden run.bat

To do relevance substitution you must wrap your relevance in single brackets { my relevance }. If you need to use a bracket in a string you must escape it by putting two {{.

Putting two brackets tells the client to ignore that bracket and then the client doesn’t enter relevance substitution mode.

That was just a pasting error but was in there. Let me try yours.

Using yours results in:
Command failed (Substitution failed while writing file) createfile until end (action:238054)

Can we try making this plural and seeing if we at least get a batch file written out?

action parameter query "name" with description "Please enter the Program Name"

delete run.bat

createfile until _end_

echo {parameter "name" of action as string as lowercase}

msiexec.exe /x {names of keys whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string as lowercase) and name of it starts with "{{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of x32 registry} /quiet /norestart

_end_

move __createfile run.bat

waithidden run.bat

The first line is an echo of the parameter you entered and if the next line just contains, “msiexec.exe /x /quiet /norestart” then your relevance isn’t returning any results on the machine

That echoed and output to the batch, but doesn’t seem to be adding the relevance portions.This is my local machine and the virtually exact command works if I don’t attempt to prompt for the parameter. Is there a limitation of a parameter within relevance?

echo snagit

msiexec.exe /x /quiet /norestart

That output implies the relevance had no result. It didn’t get an error, just no result.

I think you do not actually need to escape any of the open-curly brackets in this. You need to escape an open-curly when you are not in a Relevance Substitution, and you do not want to start one. You need to escape a close-curly when you are in a Relevance Substitution, and do not want to end the substitution.

Also, are you sure this is a 32-bit program (appearing in Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall)? You might try both registry paths…and also avoiding 64-bit redirection on the execution

Last note, I think when sending a GUID to msiexec, there shouldn’t be a space between “/x” and the GUID.

action parameter query "name" with description "Please enter the Program Name"
action uses wow64 redirection false
delete run.bat

createfile until _end_

echo {parameter "name" of action as string as lowercase}

msiexec.exe /x{names of keys whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string as lowercase) and name of it starts with "{") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)} /quiet /norestart

_end_

move __createfile run.bat

waithidden run.bat
1 Like

Listen to @JasonWalker I was incorrect on the relevance – sorry about that.

I believe the space after /x is unnecessary (i’ve never had it cause an issue) but otherwise that should fix your issue.

Jason, yours failed in a similar manner (unable to create the file).
Command failed (Substitution failed while writing file) createfile until end (action:238247)

The reason why I think it is something with the parameter queries is because if I literally change my original action:

waithidden msiexec.exe /x{name of key whose (value “DisplayName” of it as string as lowercase contains (parameter “name” of action as string as lowercase) and name of it starts with “{{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart

to this:
waithidden msiexec.exe /x{name of key whose (value “DisplayName” of it as string as lowercase contains “snagit” and name of it starts with “{”) of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry} /quiet /norestart

It works without a hitch (but is limited to the specified application)

So it seems like the problem lies in retrieving the parameter within the relevance. Because (parameter “name” of action as string as lowercase) should = snagit, but doesn’t.

Does yours work for you?

…since I have you looking at both x32 and x64 registries, it needs to be plural - keys of “HKLM…” try
msiexec.exe /x{names of keys whose (value "DisplayName" of it as string as lowercase contains (parameter "name" of action as string as lowercase) and name of it starts with "{") of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)} /quiet /norestart

(and be aware this will give problems if the given product is not found, or if more than one products match the supplied name).

That seems to work!!

So after all that, the only real change from my original seems to be using plurals instead and disabling wow64 redirection?

name = names, key to keys, and (of registries instead).

Can you explain why those changes are what made it work? Seems a little unintuitive.

Using the (x32 registries; x64 registries) allows it to check for both 32- and 64-bit applications. But since this is a plural, we cannot use the singular 'key “HKLM\Software…” - there can’t be a ‘single key’ that points to both locations.

For ‘x32 registries’, key “HKLM\Software” actually redirects to “HKLM\Software\Wow5432Node”, while the ‘x64 registries’ points to the native path of “HKLM\Software”.

Originally, before we switched to the plural “registries” and “keys”, I think the first problem was the escaping of “{{” or “}}”. But adding the problem with plurals hid from us that we had fixed the escaping a few posts back.