1

我正在使用 MsiGetProperty 从安装程序获取字符串参数值。之后,我调用了一个托管 dll 并传递了该值:

  nvBufferSize = MAX_STRING;
  MsiGetProperty (hMSI, "DBHMS", sDbHost, nvBufferSize);  

当我传递 sDbHost 的值时,当我从托管代码接收到它时是这样的:srvdata-02NULNULNULNULNULNUL...... 但是在界面中我只写了“srvdata-02”。

使用相同的代码,Installshield 2010 没问题,现在我将它升级到 installshield 2012。请问您有什么解决方案吗?

4

2 回答 2

2

不久前对 MsiGetProperty 进行了一些行为更改。尝试将 nvBufferSize 设置为 MAX_SIZE 而不是 MAX_STRING。还要检查 MsiGetProperty 的返回代码,看看它是否等于 ERROR_MORE_DATA 或者它是否返回了一些其他代码。最后检查 nvBufferSize 的值,看看需要多少字节。

顺便说一句,如果您只是想将属性编组到托管代码,您可能需要考虑查看 Windows Installer XML (WiX) 中的部署工具框架 (DTF)。这是一个非常好的 SDK,它允许您编写托管代码自定义操作并将它们打包,就好像它们是本机 Win32 库一样。InstallShield 然后可以轻松地将其用作 MSI DLL 自定义操作。

DTF 提供了一个互操作库和一个会话对象,可以像这样使用:

于 2013-05-22T11:30:33.213 回答
0

尽管看起来很荒谬,但这里有一个适合您的 InstallScript 解决方案:

nvBufferSize = MAX_STRING;
nResult = MsiGetProperty( ISMSI_HANDLE, szPropertyName, svValue, nvBufferSize );     
if( nResult = ERROR_MORE_DATA ) then 
    MsiGetProperty( ISMSI_HANDLE, szPropertyName, svValue, nvBufferSize );   
endif;

第一次尝试返回所需的实际缓冲区大小。如果它大于最大字符串(1024?),则第二次调用将获取全部内容。

或者,我发现我可以立即将 nvBufferSize 分配给更大的值,例如 4096,并在一次调用中使用它(假设数据不再是那个限制)。然而,双重调用更简单。

根据:https ://msdn.microsoft.com/en-us/library/aa370134(v= vs.85).aspx api函数实际上是设计为通过传递一个空文字(“”)而不是返回缓冲区大小一个字符串变量。如果您尝试这样做,InstallScript 2013 会向您抛出编译错误...

于 2015-08-25T22:04:25.607 回答