StdUtils plug-in: Difference between revisions
Line 407: | Line 407: | ||
== GetParameter == | == GetParameter == | ||
With ''${StdUtils.GetParameter}'' you can check for the presence of a specific command-line parameter. | |||
If the parameter was specified with a value, then the parameter's value is return. If the parameter was specified ''without'' a value, then an empty string is return. If the parameter is has '''not''' been specified, then the ''default'' value is returned. | |||
Parameters can be passed to the installer like this: | |||
* <tt>Installer.exe /Foobar</tt> | |||
* <tt>Installer.exe /Foobar=SomeValue</tt> | |||
* <tt>Installer.exe "/Foobar=Some Value With Whitespaces"</tt> | |||
<highlight-nsis>!include 'StdUtils.nsh' | <highlight-nsis>!include 'StdUtils.nsh' |
Revision as of 23:57, 8 October 2011
Author: Instructor (talk, contrib) |
This plug-in provides access to a number of "standard" functions from C Standard Library, which programmers are used to from their C/C++ compilers (and other languages), but which are not available in NSIS by default. In order to keep the plug-in size as small as possible (~9 KB) and for maximum compatibility, the Visual C++ Run-Time v6.0 (MSVCRT.DLL), which is included with all versions of Windows (since Windows 2000), is used - instead of linking the Visual C++ Run-Time library into the plug-in DLL.
Additionally this plug-in provides wrappers for the SHFileOperation function. Moreover it provides a method for launching programs in a non-elevated way (user context) from an elevated installer (admin mode) on UAC-enabled systems - see this thread for details! Last but not least, a version of ExecShell with "wait for process termination" feature, based on ShellExecuteEx, is provided.
ANSI and Unicode builds available!
Available Functions
!define StdUtils.Time '!insertmacro _StdUtils_Time' #time() !define StdUtils.Rand '!insertmacro _StdUtils_Rand' #rand() !define StdUtils.RandMax '!insertmacro _StdUtils_RandMax' #rand() with maximum !define StdUtils.RandMinMax '!insertmacro _StdUtils_RandMinMax' #rand() with minimum/maximum !define StdUtils.RandList '!insertmacro _StdUtils_RandList' #rand() with list support !define StdUtils.FormatStr '!insertmacro _StdUtils_FormatStr' #sprintf() with one format tag (only %d supported!) !define StdUtils.FormatStr2 '!insertmacro _StdUtils_FormatStr2' #sprintf() with two format tags (only %d supported!) !define StdUtils.FormatStr3 '!insertmacro _StdUtils_FormatStr3' #sprintf() with three format tags (only %d supported!) !define StdUtils.ScanStr '!insertmacro _StdUtils_ScanStr' #sscanf() with one format tag (only %d supported!) !define StdUtils.ScanStr2 '!insertmacro _StdUtils_ScanStr2' #sscanf() with two format tags (only %d supported!) !define StdUtils.ScanStr3 '!insertmacro _StdUtils_ScanStr3' #sscanf() with three format tags (only %d supported!) !define StdUtils.TrimStr '!insertmacro _StdUtils_TrimStr' #Remove whitspaces from string (left and right) !define StdUtils.TrimStrLeft '!insertmacro _StdUtils_TrimStrLeft' #Remove whitspaces from string (left side only) !define StdUtils.TrimStrRight '!insertmacro _StdUtils_TrimStrRight' #Remove whitspaces from string (right side only) !define StdUtils.SHFileMove '!insertmacro _StdUtils_SHFileMove' #SHFileOperation with FO_MOVE !define StdUtils.SHFileCopy '!insertmacro _StdUtils_SHFileCopy' #SHFileOperation with FO_COPY !define StdUtils.ExecShellAsUser '!insertmacro _StdUtils_ExecShlUser' #ShellExecute() with user context (for elevated installers) !define StdUtils.ExecShellWait '!insertmacro _StdUtils_ExecShlWait' #ShellExecuteEx() with process handle to wait for !define StdUtils.WaitForProc '!insertmacro _StdUtils_WaitForProc' #WaitForSingleObject() to wait for process termination !define StdUtils.GetParameter '!insertmacro _StdUtils_GetParameter' #Get the value of a specific commandline paramater !define StdUtils.Unload '!insertmacro _StdUtils_Unload' #Unload DLL for proper clean-up (don't forget!) !define StdUtils.SetVerbose '!insertmacro _StdUtils_SetVerbose' #Verbose mode (for debugging) !macro _StdUtils_Time out StdUtils::Time /NOUNLOAD pop ${out} !macroend !macro _StdUtils_Rand out StdUtils::Rand /NOUNLOAD pop ${out} !macroend !macro _StdUtils_RandMax out max push ${max} StdUtils::RandMax /NOUNLOAD pop ${out} !macroend !macro _StdUtils_RandMinMax out min max push ${min} push ${max} StdUtils::RandMinMax /NOUNLOAD pop ${out} !macroend !macro _StdUtils_RandList count max push ${max} push ${count} StdUtils::RandList /NOUNLOAD !macroend !macro _StdUtils_FormatStr out format val push '${format}' push ${val} StdUtils::FormatStr /NOUNLOAD pop ${out} !macroend !macro _StdUtils_FormatStr2 out format val1 val2 push '${format}' push ${val1} push ${val2} StdUtils::FormatStr2 /NOUNLOAD pop ${out} !macroend !macro _StdUtils_FormatStr3 out format val1 val2 val3 push '${format}' push ${val1} push ${val2} push ${val3} StdUtils::FormatStr3 /NOUNLOAD pop ${out} !macroend !macro _StdUtils_ScanStr out format input default push '${format}' push '${input}' push ${default} StdUtils::ScanStr /NOUNLOAD pop ${out} !macroend !macro _StdUtils_ScanStr2 out1 out2 format input default1 default2 push '${format}' push '${input}' push ${default1} push ${default2} StdUtils::ScanStr2 /NOUNLOAD pop ${out1} pop ${out2} !macroend !macro _StdUtils_ScanStr3 out1 out2 out3 format input default1 default2 default3 push '${format}' push '${input}' push ${default1} push ${default2} push ${default3} StdUtils::ScanStr3 /NOUNLOAD pop ${out1} pop ${out2} pop ${out3} !macroend !macro _StdUtils_TrimStr var push ${var} StdUtils::TrimStr /NOUNLOAD pop ${var} !macroend !macro _StdUtils_TrimStrLeft var push ${var} StdUtils::TrimStrLeft /NOUNLOAD pop ${var} !macroend !macro _StdUtils_TrimStrRight var push ${var} StdUtils::TrimStrRight /NOUNLOAD pop ${var} !macroend !macro _StdUtils_SHFileMove out from to hwnd push '${from}' push '${to}' push ${hwnd} StdUtils::SHFileMove /NOUNLOAD pop ${out} !macroend !macro _StdUtils_SHFileCopy out from to hwnd push '${from}' push '${to}' push ${hwnd} StdUtils::SHFileCopy /NOUNLOAD pop ${out} !macroend !macro _StdUtils_ExecShlUser out file verb args push '${file}' push '${verb}' push '${args}' StdUtils::ExecShellAsUser /NOUNLOAD pop ${out} !macroend !macro _StdUtils_ExecShlWait out file verb args push '${file}' push '${verb}' push '${args}' StdUtils::ExecShellWait /NOUNLOAD pop ${out} !macroend !macro _StdUtils_WaitForProc handle push '${handle}' StdUtils::WaitForProc /NOUNLOAD !macroend !macro _StdUtils_GetParameter out name default push '${name}' push '${default}' StdUtils::GetParameter /NOUNLOAD pop ${out} !macroend !macro _StdUtils_Unload StdUtils::Unload !macroend !macro _StdUtils_SetVerbose on !if "${on}" != "0" StdUtils::EnableVerboseMode /NOUNLOAD !else StdUtils::DisableVerboseMode /NOUNLOAD !endif !macroend
Example
This example tests miscellaneous functions of the StdUtils plug-in:
!include 'StdUtils.nsh' RequestExecutionLevel user ShowInstDetails show Section ${StdUtils.Time} $1 DetailPrint "Time: $1" Sleep 500 ${StdUtils.Time} $1 DetailPrint "Time: $1" Sleep 500 ${StdUtils.Time} $1 DetailPrint "Time: $1" SectionEnd Section ${StdUtils.Rand} $1 DetailPrint "Random: $1" ${StdUtils.Rand} $1 DetailPrint "Random: $1" ${StdUtils.Rand} $1 DetailPrint "Random: $1" ${StdUtils.Rand} $1 DetailPrint "Random: $1" ${StdUtils.Rand} $1 DetailPrint "Random: $1" ${StdUtils.Rand} $1 DetailPrint "Random: $1" SectionEnd Section ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" ${StdUtils.RandMax} $1 42 DetailPrint "Random Max: $1" SectionEnd Section ${StdUtils.RandMinMax} $1 -4 -2 DetailPrint "Random Min/Max: $1" ${StdUtils.RandMinMax} $1 -4 -2 DetailPrint "Random Min/Max: $1" ${StdUtils.RandMinMax} $1 -4 -2 DetailPrint "Random Min/Max: $1" ${StdUtils.RandMinMax} $1 -4 -2 DetailPrint "Random Min/Max: $1" ${StdUtils.RandMinMax} $1 -4 -2 DetailPrint "Random Min/Max: $1" ${StdUtils.RandMinMax} $1 20 21 DetailPrint "Random Min/Max: $1" SectionEnd Section ${StdUtils.FormatStr} $1 "Hello World is %05d woha!" 89 DetailPrint "FormatStr: $1" ${StdUtils.FormatStr2} $1 "Hello World is %05d and %05d woha!" 89 384 DetailPrint "FormatStr: $1" ${StdUtils.FormatStr3} $1 "Hello World is %05d and %05d or even %05d woha!" 89 384 2384 DetailPrint "FormatStr: $1" ${StdUtils.FormatStr} $1 "Hello World is %09000d." 89 DetailPrint "FormatStr: $1" SectionEnd Section ${StdUtils.RandList} 50 100 Pop $1 StrCmp $1 EOL +3 DetailPrint "RandList: $1" Goto -3 SectionEnd Section ${StdUtils.ScanStr} $0 "Der Test sagt %d ist toll!" "Der Test sagt 571 ist toll!" 42 DetailPrint "ScanStr: $0" ${StdUtils.ScanStr} $0 "Der Hund sagt %d ist toll!" "Der Test sagt 571 ist toll!" 42 DetailPrint "ScanStr: $0" SectionEnd Section ${StdUtils.ScanStr2} $0 $1 "Der Test sagt %d sowie %d ist toll!" "Der Test sagt 571 sowie 831 ist toll!" 42 43 DetailPrint "ScanStr2: $0, $1" ${StdUtils.ScanStr2} $0 $1 "Der Test sagt %d sowie %d ist toll!" "Der Test sagt 571 horch 831 ist toll!" 42 43 DetailPrint "ScanStr2: $0, $1" ${StdUtils.ScanStr2} $0 $1 "Der Test sagt %d sowie %d ist toll!" "Der Hund sagt 571 horch 831 ist toll!" 42 43 DetailPrint "ScanStr2: $0, $1" SectionEnd Section ${StdUtils.ScanStr3} $0 $1 $2 "Der Test sagt %d sowie %d ist toll! Und %d." "Der Test sagt 571 sowie 831 ist toll! Und 325" 42 43 44 DetailPrint "ScanStr3: $0, $1, $2" ${StdUtils.ScanStr3} $0 $1 $2 "Der Test sagt %d sowie %d ist toll! Und %d." "Der Test sagt 571 sowie 831 ist toll! OMG 325" 42 43 44 DetailPrint "ScanStr3: $0, $1, $2" ${StdUtils.ScanStr3} $0 $1 $2 "Der Test sagt %d sowie %d ist toll! Und %d." "Der Test sagt 571 horch 831 ist toll! OMG 325" 42 43 44 DetailPrint "ScanStr3: $0, $1, $2" ${StdUtils.ScanStr3} $0 $1 $2 "Der Test sagt %d sowie %d ist toll! Und %d." "Der Hund sagt 571 horch 831 ist toll! OMG 325" 42 43 44 DetailPrint "ScanStr3: $0, $1, $2" SectionEnd Section InitPluginsDir SetOutPath "$PLUGINSDIR\TestDirA" File "${NSISDIR}\Contrib\Graphics\Checks\*.*" SetOutPath "$PLUGINSDIR\TestDirA\SubDir" File "${NSISDIR}\Contrib\Graphics\Header\*.*" CreateDirectory "$PLUGINSDIR\SubDirX" CreateDirectory "$PLUGINSDIR\SubDirY" ${StdUtils.SHFileCopy} $0 "$PLUGINSDIR\TestDirA" "$PLUGINSDIR\SubDirX\TestDirB" $HWNDPARENT DetailPrint "SHFileCopy: $0" ${StdUtils.SHFileMove} $0 "$PLUGINSDIR\TestDirA" "$PLUGINSDIR\SubDirY\TestDirC" $HWNDPARENT DetailPrint "SHFileMove: $0" ExecShell "explore" "$PLUGINSDIR" SectionEnd Section ${StdUtils.SHFileCopy} $0 "$PLUGINSDIR\TestDirXYZ" "$PLUGINSDIR\SubDirX\TestDirZ" $HWNDPARENT DetailPrint "SHFileCopy: $0" ${StdUtils.SetVerbose} 1 ${StdUtils.SHFileCopy} $0 "$PLUGINSDIR\TestDirXYZ" "$PLUGINSDIR\SubDirX\TestDirZ" $HWNDPARENT DetailPrint "SHFileCopy: $0" ${StdUtils.SetVerbose} 0 ${StdUtils.SHFileCopy} $0 "$PLUGINSDIR\TestDirXYZ" "$PLUGINSDIR\SubDirX\TestDirZ" $HWNDPARENT DetailPrint "SHFileCopy: $0" SectionEnd Section StrCpy $1 " Some Text " StrCpy $0 $1 DetailPrint "String: '$0'" ${StdUtils.TrimStr} $0 DetailPrint "TrimStr: '$0'" StrCpy $0 $1 DetailPrint "String: '$0'" ${StdUtils.TrimStrLeft} $0 DetailPrint "TrimStrLeft: '$0'" StrCpy $0 $1 DetailPrint "String: '$0'" ${StdUtils.TrimStrRight} $0 DetailPrint "TrimStrRight: '$0'" SectionEnd Section ${StdUtils.Unload} SectionEnd
ExecShellAsUser
!include 'StdUtils.nsh' RequestExecutionLevel admin ;make sure our installer will get elevated on Vista+ with UAC enabled ShowInstDetails show Section DetailPrint 'ExecShell: "$SYSDIR\mspaint.exe"' ExecShell "open" "$SYSDIR\mspaint.exe" ;this instance of MS Paint will be elevated too! MessageBox MB_TOPMOST "Close Paint and click 'OK' to continue..." SectionEnd Section DetailPrint 'ExecShellAsUser: "$SYSDIR\mspaint.exe"' Sleep 1000 ${StdUtils.ExecShellAsUser} $0 "$SYSDIR\mspaint.exe" "open" "" ;launch a *non-elevated* instance of MS Paint DetailPrint "Result: $0" ;expected result is "ok" on UAC-enabled systems or "fallback" otherwise. Failure indicated by "error" or "timeout". ${StdUtils.Unload} ;please do not forget to unload! SectionEnd
ExecShellWait
!include 'StdUtils.nsh' RequestExecutionLevel user ShowInstDetails show Section DetailPrint 'ExecShellWait: "$SYSDIR\mspaint.exe"' Sleep 1000 ${StdUtils.ExecShellWait} $0 "$SYSDIR\mspaint.exe" "open" "" ;try to launch the process DetailPrint "Result: $0" ;returns process handle. Might be "no_wait". Failure indicated by "error". StrCmp $0 "error" WaitFailed ;check if process failed to create. StrCmp $0 "no_wait" WaitNotPossible ;check if process can be waited for. Always check this! DetailPrint "Waiting for process. ZZZzzzZZZzzz..." ${StdUtils.WaitForProc} $0 DetailPrint "Process just terminated." Goto WaitDone WaitFailed: DetailPrint "Failed to create process !!!" Goto WaitDone WaitNotPossible: DetailPrint "Can not wait for process." Goto WaitDone WaitDone: ${StdUtils.Unload} ;please do not forget to unload! SectionEnd
GetParameter
With ${StdUtils.GetParameter} you can check for the presence of a specific command-line parameter.
If the parameter was specified with a value, then the parameter's value is return. If the parameter was specified without a value, then an empty string is return. If the parameter is has not been specified, then the default value is returned.
Parameters can be passed to the installer like this:
- Installer.exe /Foobar
- Installer.exe /Foobar=SomeValue
- Installer.exe "/Foobar=Some Value With Whitespaces"
!include 'StdUtils.nsh' RequestExecutionLevel user ShowInstDetails show Section ${StdUtils.GetParameter} $R0 "Foobar" "<N/A>" StrCmp "$R0" "<N/A>" 0 +3 DetailPrint "Parameter /Foobar is *not* specified!" Goto Finished StrCmp "$R0" "" 0 +3 ;'Installer.exe [...] /Foobar' DetailPrint "Parameter /Foobar specified without a value." Goto Finished ;'Installer.exe /Foobar=Foo' or 'Installer.exe "/Foobar=Foo Bar"' ${StdUtils.TrimStr} $R0 DetailPrint "Value of parameter /Foobar is: '$R0'" Finished: ${StdUtils.Unload} ;please do not forget to unload! SectionEnd
Download
Download:
StdUtils.2011-10-09.zip (104 KB)
SVN Repository:
http://code.google.com/p/mulder/source/browse/trunk/Utils/nsis_stdutils/