Windows 安装程序,在 C++ 中访问自定义操作中的自定义属性
Posted
技术标签:
【中文标题】Windows 安装程序,在 C++ 中访问自定义操作中的自定义属性【英文标题】:Windows installer, access a custom property inside a custom action in C++ 【发布时间】:2015-02-25 01:57:17 【问题描述】:我在 Visual Studio 2010 中有一个 C++ 应用程序,并且我有一个 Windows Installer(即安装项目)来安装它。我希望能够像这样调用安装程序:
Setup1.msi MYPROPERTY=MyValue
然后能够从我的自定义操作中的属性中提取值“MyValue”。 我试图通过遵循this tutorial(C++ 自定义操作)和this tutorial(将参数传递给自定义操作,但在 C# 中)结合一些 MSDN 搜索来获得此代码:
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>
#include <msi.h>
#include <msiquery.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID)
return TRUE;
UINT APIENTRY InstallCustomAction(MSIHANDLE install_handle)
static const wchar_t* kPropertyName = L"MYPROPERTY";
//auto msi_handle = MsiGetActiveDatabase(install_handle);
DWORD n = 0;
//auto result = MsiGetProperty(msi_handle, kPropertyName, L"", &n);
auto result = MsiGetProperty(install_handle, kPropertyName, L"", &n);
wchar_t* value = nullptr;
if (result == ERROR_MORE_DATA)
++n;
value = new wchar_t[n];
//result = MsiGetProperty(msi_handle, kPropertyName, value, &n);
result = MsiGetProperty(install_handle, kPropertyName, value, &n);
if (result == ERROR_SUCCESS)
wchar_t buffer[128];
swprintf_s(buffer, L"n = %d, value = %s", n, value);
MessageBox(nullptr, buffer, L"CustomAction", MB_OK);
else
MessageBox(nullptr, L"Error reading property", L"Error", MB_OK);
delete value;
//MsiCloseHandle(msi_handle);
return ERROR_SUCCESS;
我在 IDE 方面完全遵循 C# 教程(我将 Entry Point
设置为 InstallCustomAction
和 Custom Action
数据设置为 /MYPROPERTY=[MYPROPERTY]
)自定义操作正确触发,但我没有得到参数。
使用原样的代码,我得到 n=0。如果我使用来自 MsiGetActiveDatabase
的 msi_handle
,我会收到错误消息(即 MsiGetProperty 返回的不是 ErrorSuccess)。
如何从我的自定义操作中获取用户在命令行中传入的属性?
【问题讨论】:
【参考方案1】:无需调用 MsiGetActiveDatabase。从您所写的内容看来,您的自定义操作已安排为延迟执行。在这种情况下,您应该尝试获取名为“CustomActionData”的属性。
【讨论】:
我不认为它被推迟了。我将自定义操作设置为在“安装”上触发(从安装、提交、回滚和卸载的选择中),并且在安装完成之前出现消息框。另外我不知道从我的代码中从哪里获得“CustomActionData”属性,但我确实在 IDE 中设置了该属性(我将其设置为 /MYPROPERTY=[MYPROPERTY]) 推迟了。设置项目无法以任何其他方式安排自定义操作。 所以我想我不知道 deferred 在这种情况下意味着什么。无论如何,我如何访问 CustomActionData 属性,是通过 MsiGetProperty 函数吗?我在工作中完成了所有这些,现在我在家,但我想我可以复制这个项目并尝试一下。 您实际上将为名为“CustomActionData”的属性执行 MsiGetProperty。它会像你上面描述的那样被序列化(/KEY=VALUE),你必须反序列化它。 msdn.microsoft.com/en-us/library/aa370543(v=vs.85).aspxmsdn.microsoft.com/en-us/library/2w2fhwzz(v=vs.80).aspx 这 /key-value 这是 VS 托管代码安装程序类的工作方式,这是他们的模式。在接口的某个地方,他们将字符串解析为(键,值)的字典,然后用户的托管代码使用基本安装程序类的 Context.Parameters 字典来获取值。我认为 Jeremy 可能已经看过安装程序类文档并假设 C++ CA 的工作方式相同。他们没有,而且 VS 不会将它们打包到这样的 C++ CA 中,尽管你可以使用这种格式来传递一堆参数,如果你可以像 Chris P 所说的那样自己解析它们。以上是关于Windows 安装程序,在 C++ 中访问自定义操作中的自定义属性的主要内容,如果未能解决你的问题,请参考以下文章
.net 安装程序、自定义操作、停止和卸载 windows 服务