- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有两个正在开发的应用程序,这两个应用程序都依赖于 MSIGetProductInfo 调用来检索用户在安装过程中输入的序列号(标准的 visual studio 设置和部署项目)。
这是我用来检索序列号的代码:
Int32 len = 512;
var builder = new StringBuilder(len);
MsiGetProductInfo("{98A0A10F-5E78-4FA6-83F6-6B356D75ADD4}", "ProductId", builder, ref len);
return builder.ToString();
第一个应用程序是一个可视化 C# 窗体应用程序,它按我的预期返回(当我输入 1111-1111-1111-1111 时,它会这样指示)。但是,当我在 c# windows 服务的 OnStart 方法中进行相同的调用时,我得到了随机垃圾,例如 Unicode 字符,偶尔是一个单词,并且每次运行时返回的值都不同。有时我得到的结果包含包含 MsiGetProductInfo 调用的 dll 路径的一部分,例如“㷨H꿈Eindows\system32\msi.dll”。
在我看来(无根据的猜测)对 dll 函数的调用失败了,它只是从未使用的内存位置返回数据。
我已经尝试读取其他属性,例如 InstallSource 和 InstalledProductName,但这些在服务中也是垃圾(但在表单应用程序中也很好)。我还认为这可能是权限问题,所以我尝试在 NetworkService、LocalService 和 LocalSystem 帐户下运行该服务,但没有成功。
Forms 应用程序和服务是通过同一个安装项目同时安装的,所以它们应该共享同一个 ProductCode,对吗?如果不是,我可以了解服务无法检索产品信息的原因。
有没有人遇到过这种情况或知道是什么原因造成的?
最佳答案
我需要回答同样的问题。我将 UserRegistrationDlg.wxs
添加到 wix msi 项目以收集 PIDKEY。但是,然后我需要在程序首次运行时获取安装时输入的序列号以完成激活/注册步骤。
这是我用来查询在运行时安装时输入的许可证 key 的代码(VB.NET,抱歉):
Declare Auto Function MsiGetProductInfo Lib "msi.dll" (ByVal product As String, ByVal [property] As String, <MarshalAs(UnmanagedType.VBByRefStr)> ByRef valueBuf As String, ByRef len As Long) As Int32
Private Shared Function GetMSIKey() As String
Dim lsResult As String = Nothing
Try
Dim loUninstallHive As RegistryKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall")
For Each loProgramHiveID As String In loUninstallHive.GetSubKeyNames()
Dim loProgramHive As RegistryKey = loUninstallHive.OpenSubKey(loProgramHiveID)
Dim lsProgramName As String = NullReaders.StringValue(loProgramHive.GetValue("DisplayName"))
If lsProgramName.StartsWith("<your app name>", StringComparison.OrdinalIgnoreCase) Then
Dim loInstallLocation = loProgramHive.GetValue("InstallLocation")
Dim lsHiveName As String = loProgramHive.Name
Dim lsGUID As String = lsHiveName.Substring(lsHiveName.LastIndexOf("\") + 1)
Dim lsIKC As String = New String(" ", 255)
Dim liLen As Integer = 255
MsiGetProductInfo(lsGUID, "ProductID", lsIKC, liLen)
lsResult = lsIKC.Substring(6, 24).Replace(" ", "-")
Exit For
End If
Next
Catch ex As Exception
TraceLog.DoErr(ex)
End Try
Return lsResult
End Function
请注意,ProductID
的大写字母 D 似乎很重要。
子字符串/替换将取决于 Setup.wxs
中的 PIDTemplate
属性,例如:
<Property Id="PIDTemplate"><![CDATA[12345<#### #### #### #### ####>@@@@@]]></Property>
最后,这是 UserRegistrationDlg.wxs
中将许可证 key 框放入安装程序 UI 的行:
<Control Id="CDKeyEdit" Type="MaskedEdit" X="45" Y="159" Width="250" Height="16" Property="PIDKEY" Text="[PIDTemplate]" />
关于windows - 从 Windows 服务调用 MSIGetProductInfo 返回垃圾值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7719739/
我的电脑上安装了 Microsoft Office 2013。我正在尝试使用 MsiGetProductInfo查询有关该产品的信息(实际上我需要检查是否安装了 Word)。 但以下 C++ 代码总是
我在 StackOverflow 上阅读了一些关于使用 2 个查询获取 UpgradeCode 的帖子。首先,使用 MsiGetProductInfo 获取数据库路径(如何?!)以打开将包含 Upgr
我有两个正在开发的应用程序,这两个应用程序都依赖于 MSIGetProductInfo 调用来检索用户在安装过程中输入的序列号(标准的 visual studio 设置和部署项目)。 这是我用来检索序
在使用 MSI Interop API 时,我遇到了一些导致我的应用程序崩溃的异常行为。 “处理”问题很简单,但我想更多地了解“为什么”会发生这种情况。 我对 MSIEnumRelatedProduc
我是一名优秀的程序员,十分优秀!