<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://nsis.sourceforge.io/mediawiki/index.php?action=history&amp;feed=atom&amp;title=MSI_Functions</id>
	<title>MSI Functions - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://nsis.sourceforge.io/mediawiki/index.php?action=history&amp;feed=atom&amp;title=MSI_Functions"/>
	<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=MSI_Functions&amp;action=history"/>
	<updated>2026-04-29T16:46:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://nsis.sourceforge.io/mediawiki/index.php?title=MSI_Functions&amp;diff=18238&amp;oldid=prev</id>
		<title>Zinthose: Initial Release</title>
		<link rel="alternate" type="text/html" href="https://nsis.sourceforge.io/mediawiki/index.php?title=MSI_Functions&amp;diff=18238&amp;oldid=prev"/>
		<updated>2010-03-13T01:23:48Z</updated>

		<summary type="html">&lt;p&gt;Initial Release&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{PageAuthor|Zinthose}}&lt;br /&gt;
== About ==&lt;br /&gt;
This is a preview release of my attempt to wrap the Windows Installer API functions.  Expect allot of changes to occur over the next several weeks.&lt;br /&gt;
&lt;br /&gt;
=== Current Functions ===&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;MsiGetProductInfo&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;IN&amp;#039;&amp;#039;&amp;#039;: ProductGuid&lt;br /&gt;
*** ex.{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;IN&amp;#039;&amp;#039;&amp;#039;: PropertyName&lt;br /&gt;
*** ex. ProductName&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;IN/OUT&amp;#039;&amp;#039;&amp;#039;: ReturnValue&lt;br /&gt;
*** ex. s or &amp;quot;&amp;quot; to store the value to the stack&lt;br /&gt;
*** ex. $0&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;;!define DEBUG ## Enable definition this to see additional details in the ListView&lt;br /&gt;
&lt;br /&gt;
!include MSIFunc.nsh&lt;br /&gt;
&lt;br /&gt;
OutFile MSIFunc_Example.exe&lt;br /&gt;
ShowInstDetails Show&lt;br /&gt;
&lt;br /&gt;
Section TypicalUse&lt;br /&gt;
    DetailPrint &amp;quot;### Typical Use ###&amp;quot;&lt;br /&gt;
    ## Get the Product Info for the &amp;quot;Microsoft .NET Framework 3.5 SP1&amp;quot; Package&lt;br /&gt;
        ${MsiGetProductInfo} &amp;quot;{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}&amp;quot; &amp;quot;ProductName&amp;quot; $0&lt;br /&gt;
        ${If} ${Errors}&lt;br /&gt;
            Abort $0&lt;br /&gt;
        ${EndIf}&lt;br /&gt;
        DetailPrint &amp;quot;ProductName = $0&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        ${MsiGetProductInfo} &amp;quot;{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}&amp;quot; &amp;quot;InstallDate&amp;quot; $1&lt;br /&gt;
        ${If} ${Errors}&lt;br /&gt;
            Abort &amp;quot;$1&amp;quot; &lt;br /&gt;
        ${EndIf}&lt;br /&gt;
        DetailPrint &amp;quot;InstallDate = $1&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    DetailPrint &amp;quot;&amp;quot;&lt;br /&gt;
SectionEnd&lt;br /&gt;
&lt;br /&gt;
Section UsingTheStack&lt;br /&gt;
    DetailPrint &amp;quot;### Using the Stack ###&amp;quot;&lt;br /&gt;
    ## Get the Product Info for the &amp;quot;Microsoft .NET Framework 3.5 SP1&amp;quot; Package&lt;br /&gt;
        ${MsiGetProductInfo} &amp;quot;{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}&amp;quot; &amp;quot;ProductName&amp;quot; s&lt;br /&gt;
        ${If} ${Errors}&lt;br /&gt;
            Pop $0&lt;br /&gt;
            Abort $0&lt;br /&gt;
        ${EndIf}&lt;br /&gt;
        &lt;br /&gt;
        ${MsiGetProductInfo} &amp;quot;{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}&amp;quot; &amp;quot;InstallDate&amp;quot; s&lt;br /&gt;
        ${If} ${Errors}&lt;br /&gt;
            Pop $0&lt;br /&gt;
            Abort $0&lt;br /&gt;
        ${EndIf}&lt;br /&gt;
        &lt;br /&gt;
        Pop $1&lt;br /&gt;
        Pop $0&lt;br /&gt;
        &lt;br /&gt;
        DetailPrint &amp;quot;ProductName = $0&amp;quot;&lt;br /&gt;
        DetailPrint &amp;quot;InstallDate = $1&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
SectionEnd&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSIFunc.nsh ==&lt;br /&gt;
&amp;lt;highlight-nsis&amp;gt;!ifndef ___MSIFUNC___&lt;br /&gt;
!define ___MSIFUNC___ 0.1&lt;br /&gt;
!warning &amp;quot;This is a only a Preview Release, I plan on adding ALOT more functions and perhaps even change the API for existing functions: YOU HAVE BEEN WARNED!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
!include LogicLib.nsh&lt;br /&gt;
&lt;br /&gt;
!verbose push&lt;br /&gt;
!verbose 2&lt;br /&gt;
&lt;br /&gt;
!ifndef NSIS_VERSION_MAJOR &amp;amp; NSIS_VERSION_MINOR&lt;br /&gt;
    !searchparse ${NSIS_VERSION} &amp;quot;v&amp;quot; NSIS_VERSION_MAJOR `.` NSIS_VERSION_MINOR&lt;br /&gt;
!endif&lt;br /&gt;
&lt;br /&gt;
!ifmacrondef _SetDetailsPrint&lt;br /&gt;
    !macro _SetDetailsPrint _VALUE&lt;br /&gt;
        ## FIXME [BUG] SetDetailsPrint lastused&lt;br /&gt;
        ## There is a bug that prevents lastused from working on the 2.46 version of NSIS&lt;br /&gt;
        ##   I&amp;#039;m hoping this will be fixed in the next version&lt;br /&gt;
        ##   http://sourceforge.net/tracker/?func=detail&amp;amp;aid=2969695&amp;amp;group_id=22049&amp;amp;atid=373085&lt;br /&gt;
        !if ${_VALUE} == lastused&lt;br /&gt;
            !if ${NSIS_VERSION_MAJOR}.${NSIS_VERSION_MINOR} &amp;gt; 2.46&lt;br /&gt;
                !warning `[BUG WORKAROUND SKIPPED] - If any following &amp;quot;DetailPrint&amp;quot; operations Fail try setting &amp;quot;SetDetailsPrint&amp;quot; manually.`&lt;br /&gt;
                SetDetailsPrint lastused&lt;br /&gt;
            !else&lt;br /&gt;
                !warning `[BUG WORKAROUND APPLIED] - &amp;quot;SetDetailsPrint&amp;quot; set to &amp;quot;both&amp;quot; and not &amp;quot;lastused&amp;quot;`&lt;br /&gt;
                SetDetailsPrint both&lt;br /&gt;
            !endif&lt;br /&gt;
        !else&lt;br /&gt;
            SetDetailsPrint ${_VALUE}&lt;br /&gt;
        !endif&lt;br /&gt;
    !macroend&lt;br /&gt;
    !define SetDetailsPrint `!insertmacro _SetDetailsPrint`&lt;br /&gt;
!endif&lt;br /&gt;
&lt;br /&gt;
!ifmacrondef _MsiGetProductInfo&lt;br /&gt;
    !macro _MsiGetProductInfo _PRODUCTCODE _PROPERTY _RetVar&lt;br /&gt;
        Push `${_PRODUCTCODE}`&lt;br /&gt;
        Push `${_PROPERTY}`&lt;br /&gt;
        Call MsiGetProductInfo&lt;br /&gt;
        !if &amp;#039;${_RetVar}&amp;#039; == &amp;#039;s&amp;#039;&lt;br /&gt;
        !else if &amp;#039;${_RetVar}&amp;#039; == &amp;#039;&amp;#039;&lt;br /&gt;
        !else&lt;br /&gt;
            Pop ${_RetVar} &lt;br /&gt;
        !endif&lt;br /&gt;
    !macroend&lt;br /&gt;
    !define MsiGetProductInfo `!insertmacro _MsiGetProductInfo`&lt;br /&gt;
!endif&lt;br /&gt;
&lt;br /&gt;
!macro FUNC_MsiGetProductInfo _UN&lt;br /&gt;
    Function ${_UN}MsiGetProductInfo&lt;br /&gt;
        &lt;br /&gt;
        ## If DEBUG is not defined then hide all the DetailPrint Events&lt;br /&gt;
            !ifndef DEBUG&lt;br /&gt;
                SetDetailsPrint none&lt;br /&gt;
            !endif&lt;br /&gt;
        &lt;br /&gt;
        ## Stack Protection&lt;br /&gt;
            ;Stack: _PROPERTY _PRODUCTCODE&lt;br /&gt;
            Exch $0 ; $0 _PRODUCTCODE&lt;br /&gt;
            Exch    ; _PRODUCTCODE $0&lt;br /&gt;
            Exch $1 ; $1 $0&lt;br /&gt;
            &lt;br /&gt;
            ; $0 = _PROPERTY&lt;br /&gt;
            ; $1 = _PRODUCTCODE&lt;br /&gt;
            &lt;br /&gt;
            Push $2 ; $2 $1 $0&lt;br /&gt;
            Push $3 ; $3 $2 $1 $0&lt;br /&gt;
            Push $4 ; $4 $3 $2 $1 $0&lt;br /&gt;
            Push $5 ; $5 $4 $3 $2 $1 $0&lt;br /&gt;
            &lt;br /&gt;
            ; $2 = Return Codes&lt;br /&gt;
            ; $3 = Pointer To Buffer Size&lt;br /&gt;
            ; $4 = Pointer to Buffer&lt;br /&gt;
            ; $5 = Buffer Size&lt;br /&gt;
        &lt;br /&gt;
        ## Create/Allocate a Pointer to a DWORD for the Buffer Size&lt;br /&gt;
            System::Alloc 2&lt;br /&gt;
            Pop $3&lt;br /&gt;
        &lt;br /&gt;
        ## DEBUG: &lt;br /&gt;
            !ifdef DEBUG&lt;br /&gt;
                DetailPrint &amp;quot;DEBUG: What&amp;#039;s in the registers...&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$0 = $0&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$1 = $1&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$2 = $2&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$3 = $3&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$4 = $4&amp;quot;&lt;br /&gt;
                DetailPrint &amp;quot;   $$5 = $5&amp;quot;&lt;br /&gt;
                ;MessageBox MB_OK &amp;quot;PAUSED&amp;quot;&lt;br /&gt;
            !endif&lt;br /&gt;
        &lt;br /&gt;
        ## Determine out big the buffer need to be&lt;br /&gt;
            System::Call `msi::MsiGetProductInfo(t r1,t r0,n,i $3)i .r2`&lt;br /&gt;
        &lt;br /&gt;
        ## Error Checking&lt;br /&gt;
            ${Select} $2&lt;br /&gt;
                ${Case}    0  ## ERROR_SUCCESS&lt;br /&gt;
                    DetailPrint &amp;quot;ERROR_SUCCESS - The operation completed successfully.&amp;quot;&lt;br /&gt;
                    ClearErrors&lt;br /&gt;
                ${Case} 1610  ## ERROR_BAD_CONFIGURATION&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_BAD_CONFIGURATION&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - The configuration data for product $1 is corrupt. Contact your support personnel.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case}   87  ## ERROR_INVALID_PARAMETER&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_INVALID_PARAMETER&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - The parameter is incorrect.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case}  234  ## ERROR_MORE_DATA&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_MORE_DATA&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - More data is available.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case} 1605  ## ERROR_UNKNOWN_PRODUCT&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNKNOWN_PRODUCT&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - This action is valid only for products that are currently installed.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case} 1608  ## ERROR_UNKNOWN_PROPERTY&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNKNOWN_PROPERTY&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - Unknown property.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${CaseElse}&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNANTICIPATED&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - AKA: I have no idea what happened!&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
            ${EndSelect}&lt;br /&gt;
        &lt;br /&gt;
        ## Get the requested buffer size&lt;br /&gt;
            System::Call `*$3(&amp;amp;i2 .r5)`&lt;br /&gt;
            DetailPrint &amp;quot;Requested Buffer Size = $5&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        ## Increase bufer size to account for required Null Terminator&lt;br /&gt;
            intop $5 $5 + 1&lt;br /&gt;
            System::Call `*$3(&amp;amp;i2 r5)`&lt;br /&gt;
        &lt;br /&gt;
        ## DEBUG: Display Actual buffer size&lt;br /&gt;
            !ifdef DEBUG&lt;br /&gt;
                System::Call `*$3(&amp;amp;i2 .r5)`&lt;br /&gt;
                DetailPrint &amp;quot;Actual Buffer Size = $5&amp;quot;&lt;br /&gt;
                ;MessageBox MB_OK &amp;quot;PAUSED&amp;quot;&lt;br /&gt;
            !endif&lt;br /&gt;
        &lt;br /&gt;
        ## Allocate Buffer&lt;br /&gt;
            System::Alloc $5&lt;br /&gt;
            Pop $4&lt;br /&gt;
        &lt;br /&gt;
        ## Get the Parameter Value&lt;br /&gt;
            System::Call `msi::MsiGetProductInfo(t r1,t r0,i $4,i $3)i .r2`&lt;br /&gt;
        &lt;br /&gt;
        ## Error Checking&lt;br /&gt;
            ${Select} $2&lt;br /&gt;
                ${Case}    0  ## ERROR_SUCCESS&lt;br /&gt;
                    DetailPrint &amp;quot;ERROR_SUCCESS - The operation completed successfully.&amp;quot;&lt;br /&gt;
                    ClearErrors&lt;br /&gt;
                ${Case} 1610  ## ERROR_BAD_CONFIGURATION&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_BAD_CONFIGURATION&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - The configuration data for product $1 is corrupt. Contact your support personnel.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case}   87  ## ERROR_INVALID_PARAMETER&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_INVALID_PARAMETER&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - The parameter is incorrect.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case}  234  ## ERROR_MORE_DATA&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_MORE_DATA&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - More data is available.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case} 1605  ## ERROR_UNKNOWN_PRODUCT&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNKNOWN_PRODUCT&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - This action is valid only for products that are currently installed.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${Case} 1608  ## ERROR_UNKNOWN_PROPERTY&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNKNOWN_PROPERTY&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - Unknown property.&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
                ${CaseElse}&lt;br /&gt;
                    StrCpy $0 &amp;quot;ERROR_UNANTICIPATED&amp;quot;&lt;br /&gt;
                    DetailPrint &amp;quot;$0 - AKA: I have no idea what happened!&amp;quot;&lt;br /&gt;
                    SetErrors&lt;br /&gt;
                    Goto CleanUp&lt;br /&gt;
            ${EndSelect}&lt;br /&gt;
    &lt;br /&gt;
        ## Get Value Size&lt;br /&gt;
            System::Call `*$3(&amp;amp;i2 .r5)`&lt;br /&gt;
            &lt;br /&gt;
        ## Read Property&lt;br /&gt;
            System::Call `*$4(&amp;amp;t$5 .r0)`&lt;br /&gt;
            DetailPrint &amp;quot;Property = $0&amp;quot;    &lt;br /&gt;
    &lt;br /&gt;
        ## Free Memory&lt;br /&gt;
            CleanUp:&lt;br /&gt;
            System::Free $3&lt;br /&gt;
            System::Free $4&lt;br /&gt;
        &lt;br /&gt;
        ## Restore Stack&lt;br /&gt;
                    ; $5 $4 $3 $2 $1 $0&lt;br /&gt;
            Pop $5  ; $4 $3 $2 $1 $0&lt;br /&gt;
            Pop $4  ; $3 $2 $1 $0&lt;br /&gt;
            Pop $3  ; $2 $1 $0&lt;br /&gt;
            Pop $2  ; $1 $0&lt;br /&gt;
            Pop $1  ; $0&lt;br /&gt;
            Exch $0 ; RETVALUE&lt;br /&gt;
            &lt;br /&gt;
        ## Restore DetailPrint Events&lt;br /&gt;
            !ifndef DEBUG&lt;br /&gt;
                ## FIXME [BUG] ${SetDetailsPrint}&lt;br /&gt;
                ${SetDetailsPrint} lastused&lt;br /&gt;
            !endif &lt;br /&gt;
    FunctionEnd&lt;br /&gt;
!macroend&lt;br /&gt;
!insertmacro FUNC_MsiGetProductInfo &amp;quot;&amp;quot;&lt;br /&gt;
!insertmacro FUNC_MsiGetProductInfo &amp;quot;un.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
!verbose pop&lt;br /&gt;
!endif&amp;lt;/highlight-nsis&amp;gt;&lt;br /&gt;
[[Category:System Related Functions]]&lt;/div&gt;</summary>
		<author><name>Zinthose</name></author>
	</entry>
</feed>