Skip to content
⌘ NSIS Forum Archive

How to use switch /sms?

33 posts

JohnChen#

How to use switch /sms?

I call ExecWait with the switch /sms to make the uninstaller wait until it is done. But it doesn't wait. Here is how I use it.

ExecWait '"$R0" /sms'

Here $R0 is an executable. Thanks.
JohnChen#
Originally Posted by Anders View Post
/sms is not a NSIS switch...
I see. So how can I do the similar thing like /sms in NSIS? Thanks.
JohnChen#
Originally Posted by T.Slappy View Post
What does /sms do?
/sms makes ExecWait wait until the current uninstallation is done.
JohnChen#
Originally Posted by JohnChen View Post
I call ExecWait with the switch /sms to make the uninstaller wait until it is done. But it doesn't wait. Here is how I use it.

ExecWait '"$R0" /sms'

Here $R0 is an executable. Thanks.
FYI, _?=$INSTDIR' works for me. It looks like _?=$INSTDIR' works with NSIS ExecWait. Thanks.
JohnChen#
Originally Posted by JohnChen View Post
FYI, _?=$INSTDIR' works for me. It looks like _?=$INSTDIR' works with NSIS ExecWait. Thanks.
Does any one know why _?=$INSTDIR ? I found it on the web but I don't really know what it is. Thanks.
Afrow UK#
It has nothing to do with ExecWait really. All it does is stops the uninstaller copying itself to %TEMP% and relaunching from there (i.e. spawning a new process and so the old process closes; ExecWait returns).



Stu
RaggieSoft#
An answer

/sms is an old switch from InstallShield 3 and InstallShield 5 installers (popular around the Windows 95/98 era, InstallShield 6 did away with /sms - it came out around the time of Windows 2000)

What it did:

Back then, you would see "Setup is preparing the InstallShield wizard..." along with a progress bar. That EXE would immediately exit upon launch of the main installer (I'm talking installer, not uninstaller). SMS is Microsoft's Systems Management Server (I don't think they make it any more) and calling an InstallShield EXE with /sms was how you got SMS (or any other program, like a parent installation calling a 3rd party redist installer) to WAIT for installation to finish. My guess is that InstallShield assumed most people needing to keep a parent waiting were using Microsoft's SMS (thus why the switch is "/sms")

An alternative would be the old WinZip Self-Extractor being told to wait for a program called _ISDEL to run (this would clean up InstallShield EXE temporary files after installation is completed).

Granted, these were done in enterprises long before Microsoft came out with Windows Installer, and this is the very old way to do it.


Hope this answers any questions on what /sms is. I haven't seen it discussed in years
RaggieSoft#edited
Assuming you're trying to uninstall a program from a parent uninstaller (and you want the parent uninstaller to wait for the child), here's how to duplicate:

In this example, the child program uninstaller is called uninstall.exe and the child program is installed to C:\Program Files (x86)\Program 2\

1. Your parent uninstaller needs to COPY the child's uninstaller EXE to another folder such $TEMP. This is because Windows doesn't allow an EXE to delete itself
2. the PARENT uninstaller would then call ExecWait $TEMP\uninstall.exe _?=C:\Program Files (x86)\Program 2\. (this path shouldn't be hard coded - your uninstaller should use a registry key/value (for example, as it's fastest) to grab the path of the child)
JohnChen#
Originally Posted by RaggieSoft View Post
Assuming you're trying to uninstall a program from a parent uninstaller (and you want the parent uninstaller to wait for the child), here's how to duplicate:

In this example, the child program uninstaller is called uninstall.exe and the child program is installed to C:\Program Files (x86)\Program 2\

1. Your parent uninstaller needs to COPY the child's uninstaller EXE to another folder such $TEMP. This is because Windows doesn't allow an EXE to delete itself
2. the PARENT uninstaller would then call ExecWait $TEMP\uninstall.exe _?=C:\Program Files (x86)\Program 2\. (this path shouldn't be hard coded - your uninstaller should use a registry key/value (for example, as it's fastest) to grab the path of the child)
If the uninstaller has one parameter, so I thought I should call ExecWait like this,'
ExecWait '"$0" "$1" "_?=$INSTDIR"'
Here $0 is uninstaller and $1 is its parameter. But I got an error like "Parsing Failed: Unable to open file _?". What did I wrong? Thanks.
JohnChen#
Originally Posted by Afrow UK View Post
Read the manual page that I linked to.

Stu
Actually I did. The manual page you linked to contains some examples demonstrating how to use ExecWait with _?=. But in those examples, the uninstaller doesn't take any parameter. My specific problem is related to that when the uninstaller takes one parameter, ExecWait failed with error message like "Parsing Failed: Unable to open file _?"
Here is how I did,
ExecWait '"$0" "$1" "_?=$INSTDIR"'
$0 is the uninstaller and $1 is its parameter. Is there anything wrong in this statement? Thanks.
Afrow UK#
You missed this:
It must be the last parameter used in the command line and must not contain any quotes, even if the path contains spaces.
Edit: I.e. ExecWait '"$0" "$1" _?=$INSTDIR'

Stu
JohnChen#
Originally Posted by Afrow UK View Post
You missed this:Edit: I.e. ExecWait '"$0" "$1" _?=$INSTDIR'

Stu
Unfortunately this one doesn't work either. Say if $INSTDIR = "C:\Another folder\Myfolder", I got a similar error like "Parsing Failed: Unable to open file folder\Myfolder". Notice that there is a space between "Another" and "folder".

Based on your solution, here is the summary,

ExecWait '"$0" "$1" _?=C:\Another folder\Myfolder'
error msg: Unable to open file folder\Myfolder

ExecWait '"$0" "$1" _?=C:\Temp'
error msg: Unable to open file _?

Errors above happen only when the uninstaller($0) takes one parameter. If the uninstaller doesn't take any parameter, it works fine for both cases. Any idea why? Thanks a lot.
Afrow UK#
I've never encountered that error. I will look in the source code when I can. Just to be sure, it is an NSIS uninstall executable you are running, not some other one?

Stu
JohnChen#
Originally Posted by Afrow UK View Post
I've never encountered that error. I will look in the source code when I can. Just to be sure, it is an NSIS uninstall executable you are running, not some other one?

Stu
Yes, I am sure I am running NSIS. Have you ever tried the case where you use ExecWait to run the uninstaller which takes one parameter together with "_?=" option ? Thanks.
Afrow UK#
Yes I have tried. This works:
!include MUI2.nsh

OutFile TestUninstall.exe
InstallDir $EXEDIR

!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

Section

WriteUninstaller $INSTDIR\un.exe
ExecWait `"$INSTDIR\un.exe" /a /b _?=$INSTDIR`
Delete $INSTDIR\un.exe

SectionEnd

Section Uninstall
SectionEnd
Stu
Afrow UK#
I can't find a "Parsing Failed: Unable to open file" in the source code so I highly doubt your uninstall executable is an NSIS one (i.e. generated with WriteUninstaller). NSIS only has a generic "Error launching installer" message. You do realise that _?= is specific to NSIS uninstall executables...

Stu
JohnChen#
Originally Posted by Afrow UK View Post
Yes I have tried. This works:
!include MUI2.nsh

OutFile TestUninstall.exe
InstallDir $EXEDIR

!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

Section

WriteUninstaller $INSTDIR\un.exe
ExecWait `"$INSTDIR\un.exe" /a /b _?=$INSTDIR`
Delete $INSTDIR\un.exe

SectionEnd

Section Uninstall
SectionEnd
Stu
Thanks for your reply. But /a or /b is not considered as a parameter of un.exe and they are just switch. A uninstaller with a switch works for me too. The only problem for me is that if a uninstaller takes a parameter. For example, if un.exe needs a file as an input parameter, you would call ExecWait like this,

ExecWait `"$INSTDIR\un.exe" "$INSTDIR\someFile.txt" _?=$INSTDIR`

I wonder if it works for you too? Thanks a lot.
Afrow UK#
But /a or /b is not considered as a parameter of un.exe and they are just switch.
There is no difference between a 'parameter' and a 'switch'. A program simply splits up the tokens on its command line with whitespace as the delimiter. If you tried the code yourself you'd see it works fine substituting /a with "$INSTDIR\someFile.txt".

Edit: And the uninstaller doesn't care whether the parameter begins with / or not. It only looks for the first token that begins with _?=, removes that (and proceeding tokens) and then puts the remainder into $CMDLINE which you can use from your uninstall code. It is up to your uninstaller code to handle the parameters from there.

Stu
JohnChen#
Originally Posted by Afrow UK View Post
There is no difference between a 'parameter' and a 'switch'. A program simply splits up the tokens on its command line with whitespace as the delimiter. If you tried the code yourself you'd see it works fine substituting /a with "$INSTDIR\someFile.txt".

Edit: And the uninstaller doesn't care whether the parameter begins with / or not. It only looks for the first token that begins with _?=, removes that (and proceeding tokens) and then puts the remainder into $CMDLINE which you can use from your uninstall code. It is up to your uninstaller code to handle the parameters from there.

Stu
Before I discuss further, may I ask a simple question? Who is responsible for parsing _?= part? Thanks.
JohnChen#
Originally Posted by Afrow UK View Post
I can't find a "Parsing Failed: Unable to open file" in the source code so I highly doubt your uninstall executable is an NSIS one (i.e. generated with WriteUninstaller). NSIS only has a generic "Error launching installer" message. You do realise that _?= is specific to NSIS uninstall executables...

Stu
This is very possible. Thanks for your information. Actually the uninstaller in question is a third party uninstaller. If this third party uninstaller is not a NSIS one, is there any way to make it work like a NSIS one? Thanks.
Afrow UK#
_?= is specific to NSIS uninstall executables (i.e. those generated via WriteUninstaller). The NSIS uninstaller, when executed with this option, automatically handles _?= itself. ExecWait does not handle _?= (perhaps this is what you are confused about). You can use _?= via cmd.exe or via a shortcut; it doesn't matter.

Therefore, you must be trying to execute an uninstall executable which does not know what _?= is (because it's not an NSIS uninstall executable).

Stu
Afrow UK#
If this third party uninstaller is not a NSIS one, is there any way to make it work like a NSIS one?
You'll need to find out what uninstaller it is (i.e. is it Wise, InnoSetup etc.) and determine the correct command line argument to use to prevent it from spawning a new process.

Stu
JohnChen#
Originally Posted by Afrow UK View Post
_?= is specific to NSIS uninstall executables (i.e. those generated via WriteUninstaller). The NSIS uninstaller, when executed with this option, automatically handles _?= itself. ExecWait does not handle _?= (perhaps this is what you are confused about). You can use _?= via cmd.exe or via a shortcut; it doesn't matter.

Therefore, you must be trying to execute an uninstall executable which does not know what _?= is (because it's not an NSIS uninstall executable).

Stu
How can I use WriteUninstaller in a uninstall section? In a uninstall section functions are expected to have un.. But un.WriteUninstaller is not defined. Thanks.
Afrow UK#
Are you getting confused on something else now? Look up WriteUninstaller in the manual. Perhaps you should explain what you are trying to achieve...

Stu
JohnChen#
Originally Posted by Afrow UK View Post
Are you getting confused on something else now? Look up WriteUninstaller in the manual. Perhaps you should explain what you are trying to achieve...

Stu
Actually, I was trying to use WriteUninstaller to convert a non-NSIS uninstaller to a NSIS uninstaller. But it doesn't look like it works that way. So if I get a non-NSIS uninstaller, is there any way I can use in NSIS? Thanks.
Afrow UK#
Well logically you have two options:

1. Convert the 3rd party uninstaller to NSIS by writing NSIS script
2. Execute the existing one (as you are trying to do)

The 2nd option is easiest obviously.

Stu
JohnChen#
Originally Posted by Afrow UK View Post
Well logically you have two options:

1. Convert the 3rd party uninstaller to NSIS by writing NSIS script
2. Execute the existing one (as you are trying to do)

The 2nd option is easiest obviously.

Stu
But if I choose 2nd option, the existing uninstaller doesn't know how to parse _?=. If I choose 1st option, would you please provide me a sample script how to convert the 3rd party uninstaller to NSIS? Thanks a lot.