InstallScript and Editing the Registry...
Hi there,
I hope someone here has some IinstallShield InstallScript experience and can lend a hand. I used InstallScript for a few small Custom Actions years ago, but don't really recall the guts of it.
Anyway, I want to write a IS Custom Action to add to a Basic MSI project to:
1) Grab the PackageCode
2) Grab a custom Property value from OURVERSION, which is passed to the Execute sequence via CustomActionData
3) Adjust the CurrentVersion\Uninstall DisplayVersion value.
I can basically get it to work by the following code
So, this code gets me what I want, almost. I should say what our support department wants - the application version to show and not the ProductVersion of the installer. Changing this value, to date, has caused no problems for us. We previously used WiseScript to accomplish this, but we're moving away from that.
What happens after installing is that on removal, the changed key value remains. If I don't run this code via Custom Action, the value is removed on product removal as expected. I don't know if the edit bumps some reference count or something. I did see some information regarding this in InstallShield's 2008 InstallScript users guide (use special registry functions, things being marked for uninstallation, et al), but my head is spinning after trying a multitude of compinations of the functions, constants, etc.
I hope someone can help clear this up for me and get it working the way I hope it could.
Any help, as always is greatly appreciated!
Thanks much!
I hope someone here has some IinstallShield InstallScript experience and can lend a hand. I used InstallScript for a few small Custom Actions years ago, but don't really recall the guts of it.
Anyway, I want to write a IS Custom Action to add to a Basic MSI project to:
1) Grab the PackageCode
2) Grab a custom Property value from OURVERSION, which is passed to the Execute sequence via CustomActionData
3) Adjust the CurrentVersion\Uninstall DisplayVersion value.
I can basically get it to work by the following code
function ARPDisplayVersion(hMSI)
// To Do: Declare local variables.
STRING strProdCode, strOurVersion;
NUMBER numSize;
begin
// To Do: Write script that will be executed when MyFunction is called.
numSize = 256;
// OURVERSION property passed to Execute sequence via CustomActionData:
MsiGetProperty (hMSI, "CustomActionData", strOurVersion, numSize);
MsiGetProperty (hMSI, "ProductCode", strProdCode, numSize);
RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
// Write the values to the registry. Root set above since HKCR is the default of following function...
RegDBSetKeyValueEx (REGDB_KEYPATH_UNINSTALL + "\\" + strProdCode, REGDB_VALUENAME_UNINSTALL_DISPLAYVERSION, REGDB_STRING, strOurVersion, -1);
end;
So, this code gets me what I want, almost. I should say what our support department wants - the application version to show and not the ProductVersion of the installer. Changing this value, to date, has caused no problems for us. We previously used WiseScript to accomplish this, but we're moving away from that.
What happens after installing is that on removal, the changed key value remains. If I don't run this code via Custom Action, the value is removed on product removal as expected. I don't know if the edit bumps some reference count or something. I did see some information regarding this in InstallShield's 2008 InstallScript users guide (use special registry functions, things being marked for uninstallation, et al), but my head is spinning after trying a multitude of compinations of the functions, constants, etc.
I hope someone can help clear this up for me and get it working the way I hope it could.
Any help, as always is greatly appreciated!
Thanks much!
0 Comments
[ + ] Show comments
Answers (14)
Please log in to answer
Posted by:
anonymous_9363
14 years ago
I've never delved into InstallScript so can't really help you with your problem.
What I can offer is some advice: you used to use WiseScript and are now having to migrate to InstallScript. Wouldn't it be simpler to use VBScript? There are quadzillions of sample scripts to do just about anything you might want and it works in Wise, InstallShield and externally, of course.
BTW, the uninstall registry entries are just that: registry entries. Any guff about reference-counting certainly applies to WI components and/or Windows DLLs, but not here.
What I can offer is some advice: you used to use WiseScript and are now having to migrate to InstallScript. Wouldn't it be simpler to use VBScript? There are quadzillions of sample scripts to do just about anything you might want and it works in Wise, InstallShield and externally, of course.
BTW, the uninstall registry entries are just that: registry entries. Any guff about reference-counting certainly applies to WI components and/or Windows DLLs, but not here.
Posted by:
Superfreak3
14 years ago
I can use VBScript, but since there are mixed feelings about its use (anti-virus script blocking, etc), I didn't give it a thought here.
Yeah, it is weird that after the edit via InstallScript, the key/value is not removed. I'm not getting any help from the /Flexera/InstallShield side for that either.
Yeah, it is weird that after the edit via InstallScript, the key/value is not removed. I'm not getting any help from the /Flexera/InstallShield side for that either.
Posted by:
anonymous_9363
14 years ago
Posted by:
Superfreak3
14 years ago
In any event, isn't the script you're going to be running embedded in the MSI? If so, it doesn't execute as a file.
That's true.
It's been a while since I used vbscript for a CA and they've been kind of small in nature.
I wonder if they'll be a problem with finding 64 bit registry entries or if I have to enable/disable registry redirection in the script when needed.
I can still get and Property values in the Deferred sequence using vbScript and session.property, right?
Posted by:
anonymous_9363
14 years ago
I can still get and Property values in the Deferred sequence using vbScript and session.property, right?Only 3 properties are available in the Deferred sequence: ProductCode, UserSID and CustomActionData. You can, of course, use CustomActionData to contain multiple values which you can then parse in script.
Posted by:
Superfreak3
14 years ago
Here's what seems to work...
Any pitfalls with that?
Dim objShell, ProductCode, ARPVersion, DisplayVersion
Set objShell = WScript.CreateObject("WScript.Shell")
On Error Resume Next
ProductCode = Session.Property("ProductCode")
'No need to parse CustomActionData since version is the only thing passed to it.
ARPVersion = Session.Property("CustomActionData")
DisplayVersion = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & ProductCode & "\DisplayVersion"
If objShell.RegRead (DisplayVersion) <> "" Then
objShell.RegWrite DisplayVersion, ARPVersion, "REG_SZ"
End If
WScript.Quit
Any pitfalls with that?
Posted by:
pjgeutjens
14 years ago
Posted by:
Superfreak3
14 years ago
Posted by:
anonymous_9363
14 years ago
Posted by:
Superfreak3
14 years ago
My script doesn't work when the installation is compiled for x64 machines. I guess I have to deal with registry reflection in the script if possible.
I guess I might have to use a .NET widget maybe, that is compiled for AnyCPU.
I should start looking into sending stuff to the log too as I only really rely on the custom action return code in the log currently.
I guess I might have to use a .NET widget maybe, that is compiled for AnyCPU.
I should start looking into sending stuff to the log too as I only really rely on the custom action return code in the log currently.
Posted by:
Superfreak3
14 years ago
I found the following and was messing with it. The reg read function seemed to work on both 32 and 64 bit by passing the 64 parameter. I tried to modify that function to make a write, but it writes to the 32 bit hive on a 64 bit system....
Not quite sure which way to go now.
const HKEY_LOCAL_MACHINE = &H80000002
Dim ProdCode, ARPDisplayVersion, sVersion, sKey, sValueName
sValueName = "DisplayVersion"
'ProdCode = Session.Property("ProductCode")
'ARPDisplayVersion = Session.Property("CustomActionData")
sKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{D7F05D49-5CA6-44F8-944A-D2DBB36F3625}" 'Change ending to ProdCode variable when its working.
sVersion = ReadRegStr (HKEY_LOCAL_MACHINE, sKey , sValueName, 64)
If sVersion <> "" Then
WriteRegStr HKEY_LOCAL_MACHINE, sKey, sValueName, "9.2.5.10", 64 'Change last to ARPDisplayVersion
End If
WScript.Echo sVersion
' Reads a REG_SZ value from the local computer's registry using WMI.
' Parameters:
' RootKey - The registry hive (see http://msdn.microsoft.com/en-us/library/aa390788(VS.85).aspx for a list of possible values).
' Key - The key that contains the desired value.
' Value - The value that you want to get.
' RegType - The registry bitness: 32 or 64.
'
Function ReadRegStr (RootKey, Key, Value, RegType)
Dim oCtx, oLocator, oReg, oInParams, oOutParams
Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
oCtx.Add "__ProviderArchitecture", RegType
Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")
Set oInParams = oReg.Methods_("GetStringValue").InParameters
oInParams.hDefKey = RootKey
oInParams.sSubKeyName = Key
oInParams.sValueName = Value
Set oOutParams = oReg.ExecMethod_("GetStringValue", oInParams, , oCtx)
ReadRegStr = oOutParams.sValue
set oCtx = Nothing
set oLocator = Nothing
End Function
Sub WriteRegStr (RootKey, Key, ValueName, Value, RegType)
Dim oCtx, oLocator, oReg, oInParams, oOutParams
Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
oCtx.Add "__ProviderArchitecture", RegType
Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")
Set oInParams = oReg.Methods_("SetStringValue").InParameters
oInParams.hDefKey = RootKey
oInParams.sSubKeyName = Key
oInParams.sValueName = ValueName
oInParams.sValue = Value
oReg.ExecMethod_ "SetStringValue", oInParams, , oCtx
Set oCtx = Nothing
Set oLocator = Nothing
End Sub
Not quite sure which way to go now.
Posted by:
jmcfadyen
14 years ago
Posted by:
Superfreak3
14 years ago
I have to tweak the CurrentVersion\Uninstall\{ProductCode}\DisplayVersion value for QA/Support purposes. They don't like the installer version being displayed in Add Remove Programs, but like our applications product version, #.#.#.# to be displayed there. This has to be done after RegisterProduct or any attempts to do this via the Registry table will be overwritten.
I know it may not be ideal, but that's how they want it and it has caused no problems up until now. I checked with others before doing this and since we are switching away from Wise to InstallShield, I wanted to rewrite the Custom Action.
I know it may not be ideal, but that's how they want it and it has caused no problems up until now. I checked with others before doing this and since we are switching away from Wise to InstallShield, I wanted to rewrite the Custom Action.
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
so that the conversation will remain readable.