MSI Transform - modify registry value - visual-studio-2010

I have a setup project in Visual Studio 2010 that needs to be modified in the post-build event to change a registry value. I can create a MSI transform to do that, but when I run it through msitran after the build, it fails because the Registry table entry corresponding to that key has a different Registry field value. I need a way to modify a specific registry key.
Can I create a transform that searches for a specific key? What about creating a new entry that overwrites the registry key?
What is the correct approach?

You probably need to just run a specific SQL UPDATE command rather than using a static transform that I imagine does the update based on the primary key of the record to be modified, which varies from build to build.
There is a VBS tool in the platform SDK, wirunsql.vbs, which you can use to run arbitrary SQL commands. Sounds like you want to do something along the lines of
Update Registry Set Value='MyNewValue' Where Value = 'MyUndesirableValueThatIsInvariantFromBuildToBuild'

Related

Change the value of a MSI property loaded from a DLL using a MSI transform

I need to modify the installation behavior of a MSI setup for "IBM i Access for Windows". The setup was created using InstallShield. During the installation the setup triggers two other MSI installations through "chaining". The parameters passed to MSIEXEC.EXE to execute those two installations get loaded by a custom action from a DLL that is included with the installation. The parameters end up in a MSI property.
I want to change the value in that property to manipulate the command line before the chained installation gets launched. Is this possible? If so, how? I have no problem to create an external DLL that reads and modifies the property, but I am at a loss on how to integrate this with the existing installation -- which tables do I have to modify and how, where should I put the DLL, ...
EDIT 1: To clarify this: I want to modify the parameters passed to the chained MSI installations. They are independent from the parameters I pass to the main installation and are loaded from a DLL that is part of the installation.
EDIT 2: I have uploaded the plain MSI + the relevant log file. I start the main installation with "/qn" to suppress all messages. That works without problems, the chained installations get executed without visible prompts. The problem arises when uninstalling the software (again with "/qn"). The remote custom action gets loaded from a DLL (line 6417):
MSI (s) (10:28) [09:00:45:643]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIA4BD.tmp, Entrypoint: ISChainPackages
The command line loaded from the DLL specifies to call MSIEXEC.EXE with the parameter "/qb" instead of "/qn" (line 6958):
MSI (s) (10!60) [09:00:46:033]: PROPERTY CHANGE: Adding IS_CHAINER_POST_COMMANDLINE property. Its value is '/l"c:\temp\IBM_iAccess_7.1_Uninstall.log" /qb /x{CCA40632-843E-48C6-B14F-E1070015D87C} ...
And because the MSI installer has a lock on a file a messagebox pops up triggered by the uninstallation of the chained MSI (line 44046):
MSI (s) (10:C0) [09:01:05:553]: RESTART MANAGER: Did detect that the custom action server with process ID 2352 holds file[s] in use, so a reboot will be necessary.
MSI (s) (10:C0) [09:01:05:553]: Note: 1: 1610
MSI (s) (10:C0) [09:01:11:224]: RESTART MANAGER: The user chose to go on with the installation, although a reboot will be required.
The setup must update files or services that cannot be updated while the system is running. If you choose to continue, a reboot will be required to complete the setup.
The installation files for version 7.1 of this software are no longer available on the IBM website. Only the current version is, and I have not looked into whether the problem still exists with the latest version or not as I have been asked to package v7.1 by the business department.
One approach to this problem would be to create a new Custom Action that executes VBScript code stored in the Binary Table and place the new Custom Action right after ISChainPackagePrepare. The VBScript code will read the value of IS_CHAINER_POST_COMMANDLINE and replace it as specified in the Replace() function
The VBScript Code could look like this:
Option Explicit
Function ReplacePropVal()
dim propvalue
dim newvalue
propvalue = Session.Property("IS_CHAINER_POST_COMMANDLINE")
newvalue = Replace(propvalue,"/qb","/qn")
Session.Property("IS_CHAINER_POST_COMMANDLINE") = newvalue
End Function
You want to give your new Custom Action a Type of 6 to indicate that your Custom Action data is stored as a VBScript in the Binary table. Your Custom Action Source is a reference to the Name in the Binary Table. The Target value of your Custom Action will need to be the name of the VBScript Function which is ReplacePropVal in this case
Afterwards, you place your new Custom Action in the InstallExecutionSequence table using the same name for it as in the CustomAction table. Also make sure to give it a higher Sequence value as ISChainPackagePrepare. I would recommend placing it right after by incrementing the Sequence value of ISChainPackagePrepare by 1.
After you've changed the tables and generated a new transform, just run the package with the new transform being applied by specifying its path in the TRANSFORMS public property and your property value should be changed.
I think the ideal approach here would be to transform the chained package definition. The UI level (documentation) is stored in the first two bits of the Options column of the ISChainPackage table, so all your transform should have to do is alter that value. In particular, you can change those bits from ecoUIBasic (0) to ecoUINone (1), which should be as simple as adding 1 to the current value. Also available are ecoUIReduced (2) and ecoUIFull (3).
If ISChainPackage.Options is altered correctly, the desired IS_CHAINER_POST_COMMANDLINE will be generated for you, and you won't have to add a secondary custom action to alter the /qb to /qn afterward. (Kudos to sevi for suggesting that functional workaround.)
If this is an Advanced or Suite UI Setup.exe, please check that
link for how to pass a property.
Package Database Entries (Software Re-Packaging tips for iAccess and other software):
https://www.itninja.com/company/browse/i - look at the IBM entries
IBM i Access for Windows
IBM iAccess for Windows 7.1
How to perform silent upgrade for IBM I Access for Windows 7.1?
Making a silent package for IBM i Access for Windows 7.1 with latest patch
Approaches: What does this DLL custom action do? Does it create a license key? Often these things have been found and solved many times before. To check for this, I usually use these approaches to find solutions:
File Extraction: try extracting files from the setup and look for help files that describe proper deployment. "Large Scale Deployment.chm", "Installation Command Line Parameters.chm", etc... or ready-made transforms or command line file samples (Install.cmd).
Deployment Sites: Check https://www.itninja.com/company/browse/i (Software Re-Packaging tips - look at the IBM entries. Several entries that look relevant, here is one).
Forums: inspect their support forums or online support - if available.
Phone: get on the phone with the vendor. Sometimes very helpful, often a waste of time. Ask for deployment relevant information sent from support. Do this if you have a support agreement?
See section on file extraction below.
Setup.exe Switches: I have a similar or related answer here, where I also mention setup.exe command line switches: Silent run installer (.exe) with parameters on Windows.
Logging: If the custom action does not create something dynamic (unique license key, machine locking identity, etc...), then you can try to find what was generated by logging the setup and looking for the command line used in the log file. Mock-up sample:
MSI (s) (AC:00) [00:00:00:00]: Command Line: TARGETDIR=C:\ SHORTCUTDIR=C:\Documents and Settings\All Users\Start Menu\Programs\Test ACTION=INSTALL
File Extraction: Is this an Installshield Suite project? did you extract the embedded files and MSI files first?: Programmatically extract contents of InstallShield setup.exe.
What is in a Setup.exe?: Installshield setup.exe files can be lots of different things (explanation of different setup.exe flavors): Regarding silent installation using Setup.exe generated using Installshield 2013 (.issuite) project file.
Links:
Extract MSI from EXE
What is the purpose of administrative installation initiated using msiexec /a?

How to write an encrypted value to Registry on install

During install I would like to create an encrypted string containing the install date and write that to a Registry key.
I know how to create the encrypted string in code, so I don't need help with the encryption part, I just don't know how to get the installer to:
get today's date as a string
call my encryption method on it (from a dll)
write the result to a registry key if the value does not already exists (no overwrite)
How could I do this please?
Dave
If you were using a tool that exposed more of the underlying Windows Installer such as WiX or InstallShield, you'd write a simple custom action that got the time, encrypted it and set a property. Then you would use that property in the Registry table to let the installer write it out during install, remove it during rollback and remove it during uninstall.
However, the project type you are using (and removed from VS2012 FWIW) doesn't support authoring custom actions in an immeadiate execution context and therefore the custom action can't set a property for use by the Registry table.
This means you'll have to write RollBack, Install and Uninstall custom actions yourself and write to the registry value yourself.
I'd also mention that InstallUtil custom actions have a variety of shortcomings. I'd do this either in C++ or I'd use WiX DTF to write a C# custom action that appears as a C++ DLL to the installer.

Installshield write a user defined property to the registry

I am making an installer where I have defined my own installer property. I want to store this property in the registry. As this property is only needed by the installer, I thought that the best location to store it would be:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{PRODUCT CODE}.
I use Installshield 2010 to make the installer.
What I want to know is: Is this possible and how can I do this?
Yes, this is possible. The registry values are formatted, so you can use something like this:
[MY_PROPERTY]
The location you chose is not very good. That key is used by Windows and Windows Installer internally. You can try creating your own key under SOFTWARE, for example:
HKEY_LOCAL_MACHINE\SOFTWARE\My Company\My Application

TFS explicit lock on a file that persists during a Schema Comparison -> Write Updates

Is it possible to set an explicit lock on a file in TFS?
I do Schema Comparisons in Visual Studio 2010 when porting in SQL database changes during a check-in. Clicking on "Write Updates" brings in all the changes which includes automatically unlocking any modified files. This has been wonderful up until now. I have recently introduced a new FileStream file for the database which has brought with it some complications. I can not override the physical path for the File on a configuration profile basis, so I need to add a new SqlCmd Variable that I can specify the physical path on a configuration profile basis but need to alter the schema to use the variable instead of the string (The string of the physical path in my debug environment.)
From this:
ALTER DATABASE [$(DatabaseName)]
ADD FILE (NAME = [BlobStore], FILENAME = 'C:\SQLSERVER DATA\####\BlobStream') TO FILEGROUP [BlobStreamFileGroup];
To this:
ALTER DATABASE [$(DatabaseName)]
ADD FILE (NAME = [BlobStore], FILENAME = $(PathBlobStream)) TO FILEGROUP [BlobStreamFileGroup];
It doesn't appear that I can do a reverse schema comparison to write this to the actual database on my debug environment so this is a forward integration thing only now. This means I will always have to skip the update of this schema difference in every future comparison and being a realist, I don't like the idea of potentially breaking the build if I happen to forget about it.
Is there a way to lock this schema file in TFS so that it will never being automatically unlocked/updated unless I explicitly unlock it for that purpose?
You can create another workspace on your machine, and check it out into there (use a Check-In Lock - which allows other users to check it out, but not check it in).
Then just leave it checked out/locked in your other workspace indefinately.

Is it possible to have Publisher (Manufacturer) of installation (MSI) be dynamic according to property

When we deploy our products using OEM we have a requirement that our company name will not appear in the Publisher property of the installation in the add remove / other.
although we have easy way of choosing neutral name for the publisher we would love to be able to set the name dynamic according to property for the installation (and allow our partner to add his name to it)
Is it possible?
Will that impact the sign of the MSI?
Trying to add [PROPERYNAME] to the Manufacturer property in WIX 3 didn't work as it simply set the name to include the "[PROPERTYNAME]"
Changing the MSI would invalidate the signature, and since Manufacturer is a private property, it cannot be passed in from the command line. What can work is a transform, and the transform can be signed by the vendor so it doesn't harm the aggregate signature status on Windows 7 (MSI 5.0) and up. However applying the transform also requires a command line, so that may or may not be easy, depending on your bootstrap.

Resources