/build/static/layout/Breadcrumb_cap_w.png

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

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)

Posted by: anonymous_9363 13 years ago
Red Belt
0
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.
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
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.
Posted by: anonymous_9363 13 years ago
Red Belt
0
Most clients now eschew blocking executables based solely on file extension and use (let's call it) code-signing instead.

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.
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
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 13 years ago
Red Belt
0
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 13 years ago
2nd Degree Black Belt
0
Yes I mentioned above I'm using CustomActionData.
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
Here's what seems to work...

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 13 years ago
Red Belt
0
Set objShell = WScript.CreateObject("WScript.Shell")
Wscript
.Quit


Drop the WScript's, they won't work within the context of an MSI Custom Action. Should look like this:


Set objShell = CreateObject("WScript.Shell")
Quit
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
Now to test what this will look like from both 32 and 64 bit installation packages. I wonder if this script will find things OK. I'll see I guess.
Posted by: anonymous_9363 13 years ago
Red Belt
0
MaybeIf objShell.RegRead (DisplayVersion) <> "" Then
objShell.RegWrite DisplayVersion, ARPVersion, "REG_SZ"
If objShell.RegRead (DisplayVersion) <> ARPVersion Then
'// Write failure to MSI log and/or Event log
Else
'// Write success to MSI log
End If
End If
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
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.
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
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....

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 13 years ago
5th Degree Black Belt
0
omg why are you using a CA to write registry in the first place.

sigh... only use a CA when you cannot achieve the requirement with standard actions. This could easily be covered with a conditioned reg entry in the registry table.
Posted by: Superfreak3 13 years ago
2nd Degree Black Belt
0
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.
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ