StdUtils plug-in: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m (link to proper en.wiki page)
 
(106 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{PageAuthor|Instructor}}
{{PageAuthor|LoRd MuldeR}}
[[Category:Plugins]]


This plug-in provides access to a number of "standard" functions from [http://en.wikipedia.org/wiki/C_standard_library C Standard Library], which programmers are used to from their C/C++ compilers (and other languages), but which are <i>not</i> 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.
<b>Swiss Army Knife for NSIS</b> &ndash; This plug-in provides access to a number of "standard" functions from the [[:wikipedia:C Standard Library|C Standard Library]], which programmers are used to from C/C++ and other "high level" languages, but which are <i>not</i> normally available in NSIS. In order to keep the plug-in size as small as possible and for maximum compatibility, the Visual C++ Runtime v6.0 "MSVCRT.DLL" is used, which is an integral part of all versions of Windows (since Windows 2000). This means that the C++ Runtime neither needs to be shipped as a separate DLL nor does it need to be linked <i>statically</i> into the plug-in.


Additionally this plug-in provides wrappers for the [http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164%28v=vs.85%29.aspx 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 [http://forums.winamp.com/showthread.php?t=335435 this] thread for details! Last but not least, a version of <i>ExecShell</i> with "wait for process termination" feature, based on [http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154%28v=vs.85%29.aspx ShellExecuteEx], is provided.
Many additional functions, <i>not</i> directly related to the C Standard Library, have been added over the years: For example, this plug-in provides a number convenience functions to deal with <i>strings</i>, such as trimming whitespaces or validating a given file name. There also are some functions to conveniently access the <i>command-line parameters</i> that have been passed to the installer. Furthermore, there is a wrapper for the [http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164%28v=vs.85%29.aspx SHFileOperation] function, which can be used to <i>copy or move files</i> using the Windows Shell, as well as a function to efficiently <i>append</i> the contents of one file to another file. Moreover, the plug-in provides a method for launching programs in a <i>non-elevated</i> way (aka "user mode") from an installer that is running in <i>elevated</i> context (aka "admin mode"). In addition to that, there is a set of functions that can be used to detect the <i>real</i> Windows version that the installer is running on, which still work correctly/reliably on Windows 8.1 (and later) where Microsoft has <i style="color:darkred">broken</i> the GetVersionEx() system function. And, as if this wasn't enough, the plug-in can compute the <i>cryptographic hash</i> of a given file or text message, using various state-of-the-art hash functions, including SHA-{1,2,3}. Last but not least, the plug-in provides a variant of <tt>ExecShell</tt> with "wait for process termination" feature, based on [http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154%28v=vs.85%29.aspx ShellExecuteEx], as well as a function for invoking "shell verbs" &ndash; useful for programmatically <i>pinning shortcuts to the Taskbar</i>.


<b>ANSI <i>and</i> Unicode builds available!</b>
Overall I use this plug-in as my "Swiss Army Knife" for all the small things I needed in my NSIS-based installers but that NSIS didn't provide out-of-the-box. <b>ANSI</b> <i>and</i> <b>Unicode</b> builds are provided. Supports all Windows versions, starting with <b>Windows XP</b>.


== Available Functions ==
== Available Functions ==


<highlight-nsis>!define StdUtils.Time            '!insertmacro _StdUtils_Time'        #time()
<b style="color:darkred">For details please refer to the [http://muldersoft.com/docs/stdutils_readme.html online documentation], a copy of which is also included in the download package!</b>
!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
(The documentation can be found at <tt>"Docs\StdUtils\StdUtils.html"</tt> inside the ZIP package)
push '${file}'
push '${verb}'
push '${args}'
StdUtils::ExecShellWait /NOUNLOAD
pop ${out}
!macroend


!macro _StdUtils_WaitForProc handle
=== Overview ===
push '${handle}'
StdUtils::WaitForProc /NOUNLOAD
!macroend


!macro _StdUtils_GetParameter out name default
The StdUtils plug-in makes the following functions available in NSIS:
push '${name}'
push '${default}'
StdUtils::GetParameter /NOUNLOAD
pop ${out}
!macroend


!macro _StdUtils_Unload
<highlight-nsis>!define StdUtils.Time            #time(), as in C standard library
StdUtils::Unload
!define StdUtils.GetMinutes      #GetSystemTimeAsFileTime(), returns the number of minutes
!macroend
!define StdUtils.GetHours        #GetSystemTimeAsFileTime(), returns the number of hours
!define StdUtils.GetDays          #GetSystemTimeAsFileTime(), returns the number of days
!define StdUtils.Rand            #rand(), as in C standard library
!define StdUtils.RandMax          #rand(), as in C standard library, with maximum value
!define StdUtils.RandMinMax      #rand(), as in C standard library, with minimum/maximum value
!define StdUtils.RandList        #rand(), as in C standard library, with list support
!define StdUtils.RandBytes        #Generates random bytes, returned as Base64-encoded string
!define StdUtils.FormatStr        #sprintf(), as in C standard library, one '%d' placeholder
!define StdUtils.FormatStr2      #sprintf(), as in C standard library, two '%d' placeholders
!define StdUtils.FormatStr3      #sprintf(), as in C standard library, three '%d' placeholders
!define StdUtils.ScanStr          #sscanf(), as in C standard library, one '%d' placeholder
!define StdUtils.ScanStr2        #sscanf(), as in C standard library, two '%d' placeholders
!define StdUtils.ScanStr3        #sscanf(), as in C standard library, three '%d' placeholders
!define StdUtils.TrimStr          #Remove whitspaces from string, left and right
!define StdUtils.TrimStrLeft      #Remove whitspaces from string, left side only
!define StdUtils.TrimStrRight    #Remove whitspaces from string, right side only
!define StdUtils.RevStr          #Reverse a string, e.g. "reverse me" <-> "em esrever"
!define StdUtils.ValidFileName    #Test whether string is a valid file name - no paths allowed
!define StdUtils.ValidPathSpec    #Test whether string is a valid full(!) path specification
!define StdUtils.ValidDomainName  #Test whether string is a valid host name or domain name
!define StdUtils.StrToUtf8        #Convert string from Unicode (UTF-16) or ANSI to UTF-8 bytes
!define StdUtils.StrFromUtf8      #Convert string from UTF-8 bytes to Unicode (UTF-16) or ANSI
!define StdUtils.SHFileMove      #SHFileOperation(), using the FO_MOVE operation
!define StdUtils.SHFileCopy      #SHFileOperation(), using the FO_COPY operation
!define StdUtils.AppendToFile    #Append contents of an existing file to another file
!define StdUtils.ExecShellAsUser  #ShellExecute() as NON-elevated user from elevated installer
!define StdUtils.InvokeShellVerb  #Invokes a "shell verb", e.g. for pinning items to the taskbar
!define StdUtils.ExecShellWaitEx  #ShellExecuteEx(), returns the handle of the new process
!define StdUtils.WaitForProcEx    #WaitForSingleObject(), e.g. to wait for a running process
!define StdUtils.GetParameter    #Get the value of a specific command-line option
!define StdUtils.TestParameter    #Test whether a specific command-line option has been set
!define StdUtils.ParameterCnt    #Get number of command-line tokens, similar to argc in main()
!define StdUtils.ParameterStr    #Get the n-th command-line token, similar to argv[i] in main()
!define StdUtils.GetAllParameters #Get complete command-line, but without executable name
!define StdUtils.GetRealOSVersion #Get the *real* Windows version number, even on Windows 8.1+
!define StdUtils.GetRealOSBuildNo #Get the *real* Windows build number, even on Windows 8.1+
!define StdUtils.GetRealOSName    #Get the *real* Windows version, as a "friendly" name
!define StdUtils.GetOSEdition    #Get the Windows edition, i.e. "workstation" or "server"
!define StdUtils.GetOSReleaseId  #Get the Windows release identifier (on Windows 10)
!define StdUtils.VerifyOSVersion  #Compare *real* operating system to an expected version number
!define StdUtils.VerifyOSBuildNo  #Compare *real* operating system to an expected build number
!define StdUtils.HashText        #Compute hash from text string (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.HashFile        #Compute hash from file (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.NormalizePath    #Simplifies the path to produce a direct, well-formed path
!define StdUtils.GetParentPath    #Get parent path by removing the last component from the path
!define StdUtils.SplitPath        #Split the components of the given path
!define StdUtils.GetDrivePart    #Get drive component of path
!define StdUtils.GetDirectoryPart #Get directory component of path
!define StdUtils.GetFileNamePart  #Get file name component of path
!define StdUtils.GetExtensionPart #Get file extension component of path
!define StdUtils.TimerCreate      #Create a new event-timer that will be triggered periodically
!define StdUtils.TimerDestroy    #Destroy a running timer created with TimerCreate()
!define StdUtils.ProtectStr      #Protect a given String using Windows' DPAPI
!define StdUtils.UnprotectStr    #Unprotect a string that was protected via ProtectStr()
!define StdUtils.GetLibVersion    #Get the current StdUtils library version (for debugging)
!define StdUtils.SetVerbose      #Enable or disable "verbose" mode (for debugging)</highlight-nsis>


!macro _StdUtils_SetVerbose on
== General Usage ==
!if "${on}" != "0"
StdUtils::EnableVerboseMode /NOUNLOAD
!else
StdUtils::DisableVerboseMode /NOUNLOAD
!endif
!macroend</highlight-nsis>


== Example ==
In order to use the StdUtils plug-in in your script, simply include "StdUtils.nsh" and then use the pre-defined <tt>${StdUtils.<i>FunctionName</i>}</tt> macros like this:
 
This example tests miscellaneous functions of the StdUtils plug-in:


<highlight-nsis>!include 'StdUtils.nsh'
<highlight-nsis>!include 'StdUtils.nsh'
RequestExecutionLevel user
ShowInstDetails show


Section
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
${StdUtils.Rand} $1
DetailPrint "Random: $1"
DetailPrint "Random number obtained via StdUtils::Rand is: $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</highlight-nsis>
 
== ExecShellAsUser ==
 
<highlight-nsis>!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</highlight-nsis>
SectionEnd</highlight-nsis>


== ExecShellWait ==
'''Note:''' We highly recommend to <u>not</u> call the plug-in functions directly. Instead, use the pre-defind macros from <tt>StdUtils.nsh</tt>, which will ensure that the plug-in functions are used in the "proper" way.
 
The ''${StdUtils.ExecShellWait}'' function works like the built-in ''ExecShell'' command, except that you can wait for the process to terminate. If the function failed, it returns "error". If the function succeeded, it will either return a process handle or "no_wait". The latter means that we cannot wait for the process, because ''ShellExecuteEx'' did '''not''' create a new process (but pass the file to a running instance). Only if a process handle was returned, you can call ${StdUtils.WaitForProc} in order to wait until the process has terminated.
 
<highlight-nsis>!include 'StdUtils.nsh'


RequestExecutionLevel user
For more details, please have a look at the <u>example scripts</u> located in the <tt>"Examples\StdUtils"</tt> directory of the download!
ShowInstDetails show


Section
== Acknowledgment ==
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:
* The <tt>StdUtils</tt> plug-in for NSIS was created by LoRd_MuldeR.
DetailPrint "Can not wait for process."
* This plug-in has partly been inspired by the [[ShellExecAsUser_plug-in|ShellExecAsUser]] plug-in, created by ''installer32''.
Goto WaitDone
* This plug-in has partly been inspired by the [[Invoke_Shell_Verb_plugin|InvokeShellVerb]] plug-in, created by ''Robert Strong''.
WaitDone:
${StdUtils.Unload} ;please do not forget to unload!
SectionEnd</highlight-nsis>


== GetParameter ==
== License ==


With ''${StdUtils.GetParameter}'' you can check for the presence of a specific command-line parameter.
<font size="-1"><pre>StdUtils plug-in for NSIS
Copyright (C) 2004-2015 LoRd_MuldeR <mulder2@gmx.de>


If the parameter was specified with a (non-empty) 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 has '''not''' been specified, then the ''default'' value is returned.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.


Parameters can be passed to the installer like this:
This library is distributed in the hope that it will be useful,
* <tt>Installer.exe /Foobar</tt>
but WITHOUT ANY WARRANTY; without even the implied warranty of
* <tt>Installer.exe /Foobar=SomeValue</tt>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* <tt>Installer.exe "/Foobar=Some Value With Whitespaces"</tt>
Lesser General Public License for more details.


<highlight-nsis>!include 'StdUtils.nsh'
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.</pre></font>


RequestExecutionLevel user
<small><tt>The author of the StdUtils plug-in Library for NSIS adds the following clarification to the GNU Lesser General Public License version 2.1: Installer programs (executables) created with NSIS (Nullsoft Scriptable Install System) that make use of the StdUtils plug-in Library (strictly through the NSIS plug-in interface) and that contain/distribute verbatim copies of the StdUtils plug-in Library are considered a "work that uses the Library"; they do '''not''' represent a derivative of the Library.</tt></small>
ShowInstDetails show


Section
Please see the [http://www.gnu.org/licenses/lgpl-2.1.html GNU Lesser General Public License (version 2.1)] for details!
${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"'
== Download ==
${StdUtils.TrimStr} $R0
DetailPrint "Value of parameter /Foobar is: '$R0'"
Finished:
${StdUtils.Unload} ;please do not forget to unload!
SectionEnd</highlight-nsis>


== Download ==
'''<font color="darkred">Download the <u>latest</u> version from GitHub:</font><br>https://github.com/lordmulder/stdutils/releases/latest'''


Download:<br><attach>StdUtils.2011-10-09.zip</attach>
=== Other official download mirrors ===
* http://sourceforge.net/projects/muldersoft/files/StdUtils-Plugin%20%28NSIS%29/
* https://bitbucket.org/muldersoft/stdutils/downloads
* https://www.assembla.com/spaces/stdutils/documents


SVN Repository:<br>
=== Source Code Access (Git) ===
http://code.google.com/p/mulder/source/browse/trunk/Utils/nsis_stdutils/


[[Category:Plugins]]
* https://github.com/lordmulder/stdutils.git ([https://github.com/lordmulder/stdutils Browse])
* https://gitlab.com/stdutils-plug-in-for-nsis/stdutils-plug-in-for-nsis.git ([https://gitlab.com/stdutils-plug-in-for-nsis/stdutils-plug-in-for-nsis/tree/master Browse])
* https://bitbucket.org/muldersoft/stdutils.git ([https://bitbucket.org/muldersoft/stdutils/src Browse])
* https://git.assembla.com/stdutils.git ([https://www.assembla.com/spaces/stdutils/git/source Browse])

Latest revision as of 16:42, 9 March 2022

Author: LoRd MuldeR (talk, contrib)


Swiss Army Knife for NSIS – This plug-in provides access to a number of "standard" functions from the C Standard Library, which programmers are used to from C/C++ and other "high level" languages, but which are not normally available in NSIS. In order to keep the plug-in size as small as possible and for maximum compatibility, the Visual C++ Runtime v6.0 "MSVCRT.DLL" is used, which is an integral part of all versions of Windows (since Windows 2000). This means that the C++ Runtime neither needs to be shipped as a separate DLL nor does it need to be linked statically into the plug-in.

Many additional functions, not directly related to the C Standard Library, have been added over the years: For example, this plug-in provides a number convenience functions to deal with strings, such as trimming whitespaces or validating a given file name. There also are some functions to conveniently access the command-line parameters that have been passed to the installer. Furthermore, there is a wrapper for the SHFileOperation function, which can be used to copy or move files using the Windows Shell, as well as a function to efficiently append the contents of one file to another file. Moreover, the plug-in provides a method for launching programs in a non-elevated way (aka "user mode") from an installer that is running in elevated context (aka "admin mode"). In addition to that, there is a set of functions that can be used to detect the real Windows version that the installer is running on, which still work correctly/reliably on Windows 8.1 (and later) where Microsoft has broken the GetVersionEx() system function. And, as if this wasn't enough, the plug-in can compute the cryptographic hash of a given file or text message, using various state-of-the-art hash functions, including SHA-{1,2,3}. Last but not least, the plug-in provides a variant of ExecShell with "wait for process termination" feature, based on ShellExecuteEx, as well as a function for invoking "shell verbs" – useful for programmatically pinning shortcuts to the Taskbar.

Overall I use this plug-in as my "Swiss Army Knife" for all the small things I needed in my NSIS-based installers but that NSIS didn't provide out-of-the-box. ANSI and Unicode builds are provided. Supports all Windows versions, starting with Windows XP.

Available Functions

For details please refer to the online documentation, a copy of which is also included in the download package!

(The documentation can be found at "Docs\StdUtils\StdUtils.html" inside the ZIP package)

Overview

The StdUtils plug-in makes the following functions available in NSIS:

!define StdUtils.Time             #time(), as in C standard library
!define StdUtils.GetMinutes       #GetSystemTimeAsFileTime(), returns the number of minutes
!define StdUtils.GetHours         #GetSystemTimeAsFileTime(), returns the number of hours
!define StdUtils.GetDays          #GetSystemTimeAsFileTime(), returns the number of days
!define StdUtils.Rand             #rand(), as in C standard library
!define StdUtils.RandMax          #rand(), as in C standard library, with maximum value
!define StdUtils.RandMinMax       #rand(), as in C standard library, with minimum/maximum value
!define StdUtils.RandList         #rand(), as in C standard library, with list support
!define StdUtils.RandBytes        #Generates random bytes, returned as Base64-encoded string
!define StdUtils.FormatStr        #sprintf(), as in C standard library, one '%d' placeholder
!define StdUtils.FormatStr2       #sprintf(), as in C standard library, two '%d' placeholders
!define StdUtils.FormatStr3       #sprintf(), as in C standard library, three '%d' placeholders
!define StdUtils.ScanStr          #sscanf(), as in C standard library, one '%d' placeholder
!define StdUtils.ScanStr2         #sscanf(), as in C standard library, two '%d' placeholders
!define StdUtils.ScanStr3         #sscanf(), as in C standard library, three '%d' placeholders
!define StdUtils.TrimStr          #Remove whitspaces from string, left and right
!define StdUtils.TrimStrLeft      #Remove whitspaces from string, left side only
!define StdUtils.TrimStrRight     #Remove whitspaces from string, right side only
!define StdUtils.RevStr           #Reverse a string, e.g. "reverse me" <-> "em esrever"
!define StdUtils.ValidFileName    #Test whether string is a valid file name - no paths allowed
!define StdUtils.ValidPathSpec    #Test whether string is a valid full(!) path specification
!define StdUtils.ValidDomainName  #Test whether string is a valid host name or domain name
!define StdUtils.StrToUtf8        #Convert string from Unicode (UTF-16) or ANSI to UTF-8 bytes
!define StdUtils.StrFromUtf8      #Convert string from UTF-8 bytes to Unicode (UTF-16) or ANSI
!define StdUtils.SHFileMove       #SHFileOperation(), using the FO_MOVE operation
!define StdUtils.SHFileCopy       #SHFileOperation(), using the FO_COPY operation
!define StdUtils.AppendToFile     #Append contents of an existing file to another file
!define StdUtils.ExecShellAsUser  #ShellExecute() as NON-elevated user from elevated installer
!define StdUtils.InvokeShellVerb  #Invokes a "shell verb", e.g. for pinning items to the taskbar
!define StdUtils.ExecShellWaitEx  #ShellExecuteEx(), returns the handle of the new process
!define StdUtils.WaitForProcEx    #WaitForSingleObject(), e.g. to wait for a running process
!define StdUtils.GetParameter     #Get the value of a specific command-line option
!define StdUtils.TestParameter    #Test whether a specific command-line option has been set
!define StdUtils.ParameterCnt     #Get number of command-line tokens, similar to argc in main()
!define StdUtils.ParameterStr     #Get the n-th command-line token, similar to argv[i] in main()
!define StdUtils.GetAllParameters #Get complete command-line, but without executable name
!define StdUtils.GetRealOSVersion #Get the *real* Windows version number, even on Windows 8.1+
!define StdUtils.GetRealOSBuildNo #Get the *real* Windows build number, even on Windows 8.1+
!define StdUtils.GetRealOSName    #Get the *real* Windows version, as a "friendly" name
!define StdUtils.GetOSEdition     #Get the Windows edition, i.e. "workstation" or "server"
!define StdUtils.GetOSReleaseId   #Get the Windows release identifier (on Windows 10)
!define StdUtils.VerifyOSVersion  #Compare *real* operating system to an expected version number
!define StdUtils.VerifyOSBuildNo  #Compare *real* operating system to an expected build number
!define StdUtils.HashText         #Compute hash from text string (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.HashFile         #Compute hash from file (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.NormalizePath    #Simplifies the path to produce a direct, well-formed path
!define StdUtils.GetParentPath    #Get parent path by removing the last component from the path
!define StdUtils.SplitPath        #Split the components of the given path
!define StdUtils.GetDrivePart     #Get drive component of path
!define StdUtils.GetDirectoryPart #Get directory component of path
!define StdUtils.GetFileNamePart  #Get file name component of path
!define StdUtils.GetExtensionPart #Get file extension component of path
!define StdUtils.TimerCreate      #Create a new event-timer that will be triggered periodically
!define StdUtils.TimerDestroy     #Destroy a running timer created with TimerCreate()
!define StdUtils.ProtectStr       #Protect a given String using Windows' DPAPI
!define StdUtils.UnprotectStr     #Unprotect a string that was protected via ProtectStr()
!define StdUtils.GetLibVersion    #Get the current StdUtils library version (for debugging)
!define StdUtils.SetVerbose       #Enable or disable "verbose" mode (for debugging)

General Usage

In order to use the StdUtils plug-in in your script, simply include "StdUtils.nsh" and then use the pre-defined ${StdUtils.FunctionName} macros like this:

!include 'StdUtils.nsh'
 
Section
	${StdUtils.Rand} $1
	DetailPrint "Random number obtained via StdUtils::Rand is: $1"
SectionEnd

Note: We highly recommend to not call the plug-in functions directly. Instead, use the pre-defind macros from StdUtils.nsh, which will ensure that the plug-in functions are used in the "proper" way.

For more details, please have a look at the example scripts located in the "Examples\StdUtils" directory of the download!

Acknowledgment

  • The StdUtils plug-in for NSIS was created by LoRd_MuldeR.
  • This plug-in has partly been inspired by the ShellExecAsUser plug-in, created by installer32.
  • This plug-in has partly been inspired by the InvokeShellVerb plug-in, created by Robert Strong.

License

StdUtils plug-in for NSIS
Copyright (C) 2004-2015 LoRd_MuldeR <mulder2@gmx.de>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.

The author of the StdUtils plug-in Library for NSIS adds the following clarification to the GNU Lesser General Public License version 2.1: Installer programs (executables) created with NSIS (Nullsoft Scriptable Install System) that make use of the StdUtils plug-in Library (strictly through the NSIS plug-in interface) and that contain/distribute verbatim copies of the StdUtils plug-in Library are considered a "work that uses the Library"; they do not represent a derivative of the Library.

Please see the GNU Lesser General Public License (version 2.1) for details!

Download

Download the latest version from GitHub:
https://github.com/lordmulder/stdutils/releases/latest

Other official download mirrors

Source Code Access (Git)