StdUtils plug-in: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m (link to proper en.wiki page)
 
(110 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
(The documentation can be found at <tt>"Docs\StdUtils\StdUtils.html"</tt> inside the ZIP package)
push '${file}'
push '${verb}'
push '${args}'
StdUtils::ExecShellAsUser /NOUNLOAD
pop ${out}
!macroend


!macro _StdUtils_ExecShlWait out file verb args
=== Overview ===
push '${file}'
push '${verb}'
push '${args}'
StdUtils::ExecShellWait /NOUNLOAD
pop ${out}
!macroend


!macro _StdUtils_WaitForProc handle
The StdUtils plug-in makes the following functions available in NSIS:
push '${handle}'
StdUtils::WaitForProc /NOUNLOAD
!macroend


!macro _StdUtils_GetParameter out name default
<highlight-nsis>!define StdUtils.Time            #time(), as in C standard library
push '${name}'
!define StdUtils.GetMinutes      #GetSystemTimeAsFileTime(), returns the number of minutes
push '${default}'
!define StdUtils.GetHours        #GetSystemTimeAsFileTime(), returns the number of hours
StdUtils::GetParameter /NOUNLOAD
!define StdUtils.GetDays          #GetSystemTimeAsFileTime(), returns the number of days
pop ${out}
!define StdUtils.Rand            #rand(), as in C standard library
!macroend
!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_Unload
== General Usage ==
StdUtils::Unload
!macroend


!macro _StdUtils_SetVerbose on
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:
!if "${on}" != "0"
StdUtils::EnableVerboseMode /NOUNLOAD
!else
StdUtils::DisableVerboseMode /NOUNLOAD
!endif
!macroend</highlight-nsis>
 
== Example ==


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


== ExecShellAsUser ==
'''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.


<highlight-nsis>!include 'StdUtils.nsh'
For more details, please have a look at the <u>example scripts</u> located in the <tt>"Examples\StdUtils"</tt> directory of the download!


RequestExecutionLevel admin ;make sure our installer will get elevated on Vista+ with UAC enabled
== Acknowledgment ==
ShowInstDetails show


Section
* The <tt>StdUtils</tt> plug-in for NSIS was created by LoRd_MuldeR.
DetailPrint 'ExecShell: "$SYSDIR\mspaint.exe"'
* This plug-in has partly been inspired by the [[ShellExecAsUser_plug-in|ShellExecAsUser]] plug-in, created by ''installer32''.
ExecShell "open" "$SYSDIR\mspaint.exe" ;this instance of MS Paint will be elevated too!
* This plug-in has partly been inspired by the [[Invoke_Shell_Verb_plugin|InvokeShellVerb]] plug-in, created by ''Robert Strong''.
MessageBox MB_TOPMOST "Close Paint and click 'OK' to continue..."
SectionEnd


Section
== License ==
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>


== ExecShellWait ==
<font size="-1"><pre>StdUtils plug-in for NSIS
Copyright (C) 2004-2015 LoRd_MuldeR <mulder2@gmx.de>


<highlight-nsis>!include 'StdUtils.nsh'
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.


RequestExecutionLevel user
This library is distributed in the hope that it will be useful,
ShowInstDetails show
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.


Section
You should have received a copy of the GNU Lesser General Public
DetailPrint 'ExecShellWait: "$SYSDIR\mspaint.exe"'
License along with this library; if not, write to the Free Software
Sleep 1000
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.</pre></font>
${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:
<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>
DetailPrint "Can not wait for process."
Goto WaitDone
WaitDone:
${StdUtils.Unload} ;please do not forget to unload!
SectionEnd</highlight-nsis>


== GetParameter ==
Please see the [http://www.gnu.org/licenses/lgpl-2.1.html GNU Lesser General Public License (version 2.1)] for details!


<highlight-nsis>!include 'StdUtils.nsh'
== Download ==
 
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</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)