<p>I need to know the application's ProductCode in the Installer.OnCommitted callback. There doesn't seem to be an obvious way of determining this.</p>

[{'answer_id': 61069, 'author': 'Chris Tybur', 'author_id': 741, 'author_profile': 'https://Stackoverflow.com/users/741', 'pm_score': 0, 'selected': False, 'text': "<p>The MSI function MsiGetProperty can be used to get the name of the ProductCode property. I don't know if that would work in this case, since I've never created a .NET installer.</p>\n"}, {'answer_id': 61298, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': '<p>I ended up passing the product code as a command line argument to my Installer class using the CustomActionData property in Visual Studio (e.g. /productcode={31E1145F-B833-47c6-8C80-A55F306B8A6C}.\nI can then access this from any callback within the Installer class using the Context.Parameters StringDictionary</p>\n\n<pre><code>string productCode = (string)Context.Parameters["productcode"];\n</code></pre>\n'}, {'answer_id': 1213739, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': '<p>You can avoid hardcoding your product code, using /productCode=[ProductCode] in your CustomActionData property.</p>\n'}, {'answer_id': 67385558, 'author': 'aolszowka', 'author_id': 433069, 'author_profile': 'https://Stackoverflow.com/users/433069', 'pm_score': 0, 'selected': False, 'text': '<p>The suggestion from @Chris Tybur seems to work</p>\n<p>Here\'s my C# Code:</p>\n<pre class="lang-cs prettyprint-override"><code>        public static string GetProductCode(string fileName)\n        {\n            IntPtr hInstall = IntPtr.Zero;\n            try\n            {\n                uint num = MsiOpenPackage(fileName, ref hInstall);\n                if ((ulong)num != 0)\n                {\n                    throw new Exception(&quot;Cannot open database: &quot; + num);\n                }\n\n                int pcchValueBuf = 255;\n                StringBuilder szValueBuf = new StringBuilder(pcchValueBuf);\n                num = MsiGetProperty(hInstall, &quot;ProductCode&quot;, szValueBuf, ref pcchValueBuf);\n                if ((ulong)num != 0)\n                {\n                    throw new Exception(&quot;Failed to Get Property ProductCode: &quot; + num);\n                }\n                return szValueBuf.ToString();\n            }\n            finally\n            {\n                if (hInstall != IntPtr.Zero)\n                {\n                    MsiCloseHandle(hInstall);\n                }\n            }\n        }\n\n        [DllImport(&quot;msi.dll&quot;, CharSet = CharSet.Unicode, EntryPoint = &quot;MsiGetPropertyW&quot;, ExactSpelling = true, SetLastError = true)]\n        private static extern uint MsiGetProperty(IntPtr hInstall, string szName, [Out] StringBuilder szValueBuf, ref int pchValueBuf);\n        [DllImport(&quot;msi.dll&quot;, CharSet = CharSet.Unicode, EntryPoint = &quot;MsiOpenPackageW&quot;, ExactSpelling = true, SetLastError = true)]\n        private static extern uint MsiOpenPackage(string szDatabasePath, ref IntPtr hProduct);\n        [DllImport(&quot;msi.dll&quot;, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]\n        private static extern int MsiCloseHandle(IntPtr hAny);\n\n</code></pre>\n<p>FWIW: There is a small blurb on this MSDN Site that might be cause for concern: <a href="https://learn.microsoft.com/en-us/windows/win32/msi/obtaining-context-information-for-deferred-execution-custom-actions" rel="nofollow noreferrer">https://learn.microsoft.com/en-us/windows/win32/msi/obtaining-context-information-for-deferred-execution-custom-actions</a></p>\n<pre><code>Function    Description\nMsiGetProperty  Supports a limited set of properties when used with deferred execution custom actions:\n                the CustomActionData property, ProductCode property, and UserSID property.Commit custom\n                actions cannot use the MsiGetProperty function to obtain the ProductCode property.\n                Commit custom actions can use the CustomActionData property to obtain the product code.\n</code></pre>\n<p>Note the call out <code>cannot use the MsiGetProperty function to obtain the ProductCode property</code>. So YMMV.</p>\n<p>Reviewing <a href="https://stackoverflow.com/questions/29937568/how-can-i-find-the-product-guid-of-an-installed-msi-setup">How can I find the product GUID of an installed MSI setup?</a> you can use the COM API to gather this (the current version shows a VBScript) which might be worth inspecting as well.</p>\n'}]
['https://Stackoverflow.com/questions/61052', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/-1/']