可视化如何从C++自定义操作获取 MSI 'UILevel'属性
visual How to Obtain the MSI 'UILevel' Property From a C++ Custom Action
我正在尝试从C 自定义操作中获取'Uilevel'MSI属性有很多运气。我正在调用的函数通过我在DLL中导出的函数传递(可能是"延期"或"首先"操作)。我看到的是MsiGetPropertyW
总是返回ERROR_MORE_DATA
,trueLength
字段始终为0。这是我的代码:
bool runningInNoUIMode(MSIHANDLE hInstall)
{
unsigned long nBufLen = 64UL;
WCHAR *wszValue = new WCHAR[nBufLen];
DWORD trueLength = 0UL;
UINT result = ::MsiGetPropertyW(hInstall, L"UILevel", L"", &trueLength); // Get the size of the property value first to see if there is enough storage allocated.
if (ERROR_MORE_DATA == result || nBufLen <= trueLength)
{
if (NULL != wszValue)
{
delete [] wszValue;
}
// Allocate more memory for the property adding one for the null terminator.
nBufLen = trueLength + 1;
wszValue = new WCHAR[nBufLen];
}
if (NULL == wszValue)
{
WcaLog(LOGMSG_STANDARD, "Unable to determine the user interface level the MSI is being run with because we were unable to allocate storage for accessing the 'UILevel' property.");
return false;
}
memset(wszValue, L' ', nBufLen * sizeof(WCHAR));
result = ::MsiGetPropertyW(hInstall, L"UILevel", wszValue, &trueLength);
if (ERROR_SUCCESS != result)
{
WcaLog(LOGMSG_STANDARD, "Unable to determine the user interface level the MSI is being run with, error code = '%lu'.", result);
delete [] wszValue;
return false;
}
if (0 == wcscmp(L"2", wszValue)) // INSTALLUILEVEL_NONE == 2
{
delete [] wszValue;
return true;
}
delete [] wszValue;
return false;
}
我相信我现在可以通过Wix传递" Uilevel"属性并在C 中进行检查,但我很好奇这里的问题也是什么。
我正在使用Windows 7上的Visual Studio/Visual C 2010,Wix 3.5.2519。
感谢您提供的任何帮助!
使此更简单的另一种方法是使用MSIEVALUATECONTICE函数。
BOOL bUI = MsiEvaluateCondition(L"UILevel<3");
在c#中使用microsoft.deployment.windowsintaller(dtf)是:
var uiLevel = session["UILevel"];
在C 中,MSIgetProperty函数有一个样本:
UINT __stdcall MyCustomAction(MSIHANDLE hInstall)
{
TCHAR* szValueBuf = NULL;
DWORD cchValueBuf = 0;
UINT uiStat = MsiGetProperty(hInstall, TEXT("MyProperty"), TEXT(""), &cchValueBuf);
//cchValueBuf now contains the size of the property's string, without null termination
if (ERROR_MORE_DATA == uiStat)
{
++cchValueBuf; // add 1 for null termination
szValueBuf = new TCHAR[cchValueBuf];
if (szValueBuf)
{
uiStat = MsiGetProperty(hInstall, TEXT("MyProperty"), szValueBuf, &cchValueBuf);
}
}
if (ERROR_SUCCESS != uiStat)
{
if (szValueBuf != NULL)
delete[] szValueBuf;
return ERROR_INSTALL_FAILURE;
}
// custom action uses MyProperty
// ...
delete[] szValueBuf;
return ERROR_SUCCESS;
}
感谢@danielgehriger,我们发现问题不是代码,而是针对自定义操作的计划。运行deferred
自定义操作时,UILevel
MSI属性简单不可用(我发现该代码适用于为firstsequence
安排的自定义操作工作。我通过使用Wix在自定义操作数据上明确将其传递到了这种限制:
<CustomAction Id="CustomAction.SetProperty" Property="CustomActionCall"
Value="UILEVEL=[UILevel];" />
,然后使用WcaIsPropertySet
和WcaGetProperty
在C 中检查一下。请注意,方括号之间的属性名称的字符很重要。
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- C++概念:如何使用'concept'检查模板化结构的属性?
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 通过指向指针数组的指针访问子类的属性
- MSVC是否支持C++11样式的属性而不是__declspec
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 类的C++属性似乎已重新初始化
- Qt Quick-如何仅从c++代码与qml属性交互
- 用概念检查属性的类型
- C++如何将同一类的实例作为属性
- 按多个属性排序
- 主函数参数的属性
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- C++删除未使用的类属性会导致 std::logic_error
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 使用内存地址访问结构的属性值
- C++调用具有 *this 属性的单个帮助程序函数
- 如何在自定义操作DLL(MSI / Wix)中获取"INSTALLED"属性?
- 可视化如何从C++自定义操作获取 MSI 'UILevel'属性
- 获取MSI产品属性