string too long with MsiGetProperty with Installsh

2019-07-29 22:45发布

I am using MsiGetProperty to get string parameter value from the installer. And after that I am calling a managed dll and I pass the that value:

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

when I pass the value of sDbHost is like this when I receive it from managed code: srvdata-02NULNULNULNULNULNUL...... however in the interface I wrote just "srvdata-02".

With that same code it was fine with Installshield 2010, now I am upgrading it to installshield 2012. Do you have any solution with that please?

2条回答
We Are One
2楼-- · 2019-07-29 23:12

As ridiculous as it may seem, here's a working InstallScript solution for you:

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

The first attempt returns the actual buffer size needed. If it is more then max string (1024?), the second call gets the whole thing.

Alternatively, I found I could assign nvBufferSize to larger value right off the bat e.g. 4096 and use that with a single call (assuming the data was no longer that limit). The double call, however, is more fool proof.

According to: https://msdn.microsoft.com/en-us/library/aa370134(v=vs.85).aspx the api function is actually designed to return the buffersize by passing an empty literal ("") instead of a string variable. InstallScript 2013 throws a compilation error at you if you try that though...

查看更多
Emotional °昔
3楼-- · 2019-07-29 23:16

There were some behavior changes to MsiGetProperty awhile back. Try setting nvBufferSize to MAX_SIZE instead of MAX_STRING. Also check the return code of MsiGetProperty to see if it equals ERROR_MORE_DATA or if it's returning some other code. Finally check the value of nvBufferSize to see how many bytes are needed.

BTW, if you are just trying to marshal a property over to managed code, you might want to conisder looking into Deployment Tools Framework (DTF) in Windows Installer XML (WiX). This is a very nice SDK that allows you to write managed code custom actions and package them up as if they are native Win32 libraries. InstallShield can then easily use this as an MSI DLL custom action.

DTF provides an interop library and a session object that can be used like:

查看更多
登录 后发表回答