string too long with MsiGetProperty with Installshield Installscript
Asked Answered
F

2

1

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?

Fortuna answered 22/5, 2013 at 11:8 Comment(0)
F
2

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:

Ferroconcrete answered 22/5, 2013 at 11:30 Comment(2)
MAX_SIZE is not defined in InstallShield 2013.Dejadeject
Guess not. It's funny, after 20 years I've forgotten more about InstallScript then I remember.Ferroconcrete
D
0

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...

Dejadeject answered 25/8, 2015 at 22:4 Comment(4)
Take it a step further and wrap it into a helper function. Ya, this is how it works.... can't say I really use InstallScript much these days though. Usually I just go with a DTF / C# custom action since .NET 2.0 or newer should be on pretty much every machine by now.Ferroconcrete
I agree. Ideally you'd stick this in a function within a utility include script. I understand your movement away from InstallScript. I use it within InstallShield essentially for the "continuity" of it all.Dejadeject
InstallScript peaked for me about 10 years ago. blog.iswix.com/2005/03/custom-actions.html blog.iswix.com/2006/04/installshield-12-beta2.htmlFerroconcrete
IMO, it's a decent language. It started in a time when doing equivalent things in C++ was a lot more work. They tacked on COM and .NET interop over the years. However WiX DTF/C# custom actions integrate into InstallShield very nicely. A fully patched Windows XP box will have .NET 2.0. Vista came with 3.0 and so on. I write my CA's for CLR 2.0 and include a CustomAction config file that says to bind to 2.0 or 4.0. Now I'm able to leverage the full power of the base class libraries and there's nothing it can't do that InstallScript can. That said build automation takes a little more work.Ferroconcrete

© 2022 - 2024 — McMap. All rights reserved.