1

我需要在 Installer.OnCommitted 回调中知道应用程序的 ProductCode。似乎没有一种明显的方法来确定这一点。

4

4 回答 4

2

您可以避免对产品代码进行硬编码,在 CustomActionData 属性中使用 /productCode=[ProductCode]。

于 2009-07-31T17:08:52.893 回答
1

我最终使用 Visual Studio 中的 CustomActionData 属性将产品代码作为命令行参数传递给我的安装程序类(例如 /productcode={31E1145F-B833-47c6-8C80-A55F306B8A6C}。然后我可以从使用 Context.Parameters StringDictionary 的安装程序类

string productCode = (string)Context.Parameters["productcode"];
于 2008-09-14T12:18:39.967 回答
0

MSI 函数 MsiGetProperty 可用于获取 ProductCode 属性的名称。我不知道这在这种情况下是否可行,因为我从未创建过 .NET 安装程序。

于 2008-09-14T02:24:02.000 回答
0

@Chris Tybur 的建议似乎有效

这是我的 C# 代码:

        public static string GetProductCode(string fileName)
        {
            IntPtr hInstall = IntPtr.Zero;
            try
            {
                uint num = MsiOpenPackage(fileName, ref hInstall);
                if ((ulong)num != 0)
                {
                    throw new Exception("Cannot open database: " + num);
                }

                int pcchValueBuf = 255;
                StringBuilder szValueBuf = new StringBuilder(pcchValueBuf);
                num = MsiGetProperty(hInstall, "ProductCode", szValueBuf, ref pcchValueBuf);
                if ((ulong)num != 0)
                {
                    throw new Exception("Failed to Get Property ProductCode: " + num);
                }
                return szValueBuf.ToString();
            }
            finally
            {
                if (hInstall != IntPtr.Zero)
                {
                    MsiCloseHandle(hInstall);
                }
            }
        }

        [DllImport("msi.dll", CharSet = CharSet.Unicode, EntryPoint = "MsiGetPropertyW", ExactSpelling = true, SetLastError = true)]
        private static extern uint MsiGetProperty(IntPtr hInstall, string szName, [Out] StringBuilder szValueBuf, ref int pchValueBuf);
        [DllImport("msi.dll", CharSet = CharSet.Unicode, EntryPoint = "MsiOpenPackageW", ExactSpelling = true, SetLastError = true)]
        private static extern uint MsiOpenPackage(string szDatabasePath, ref IntPtr hProduct);
        [DllImport("msi.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
        private static extern int MsiCloseHandle(IntPtr hAny);

FWIW:此 MSDN 站点上有一个可能引起关注的小信息:https ://docs.microsoft.com/en-us/windows/win32/msi/obtaining-context-information-for-deferred-execution-自定义动作

Function    Description
MsiGetProperty  Supports a limited set of properties when used with deferred execution custom actions:
                the CustomActionData property, ProductCode property, and UserSID property.Commit custom
                actions cannot use the MsiGetProperty function to obtain the ProductCode property.
                Commit custom actions can use the CustomActionData property to obtain the product code.

注意呼出cannot use the MsiGetProperty function to obtain the ProductCode property。所以YMMV。

查看如何找到已安装 MSI 设置的产品 G​​UID?您可以使用 COM API 来收集它(当前版本显示 VBScript),这可能也值得检查。

于 2021-05-04T13:17:00.410 回答