MSI adding properties and self elevation

The self elevation is needed for installers that use restricted resources or perform some administrative operations on the client machine (Vista and higher). The installer should show then a UAC message saying that the credentials of the administrator should be entered to proceed.
To do this right with Visual Studio 2005/2008 is quite impossible because they do not provide enough options to customize the MSI installers (although it is they who stand behind these installation packages).
So we need two things: first we would like to have a tool that knows to add new properties and the second is to know the exact property that should be changed.
We can use Orca for the first task but it may look to complicate. Instead I suggest to use the following JavaScript code that I've found on the web:
// MSI_SetProperty.js <msi-file> <property> <value>
// we use //MSIUSEREALADMINDETECTION 1
// Performs a post-build fixup of an MSI to set the specified property (and add it if it doesn't already exist)
// Constant values from Windows Installer SDK
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyInsert = 1;
var msiViewModifyUpdate = 2;
if (WScript.Arguments.Length != 3)
{
WScript.StdErr.WriteLine("Usage: " + WScript.ScriptName + "file property value");
WScript.Quit(1);
}
var filespec = WScript.Arguments(0);
var property = WScript.Arguments(1);
var value = parseInt(WScript.Arguments(2));
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
WScript.StdOut.WriteLine("Looking for property:" + property);
try
{
var sql = "SELECT Property, Value FROM Property WHERE Property = '" + property + "'";
var view = database.OpenView(sql);
view.Execute();
var record = view.Fetch();
if (record)
{
while (record)
{
WScript.StdOut.Write("Found: " + record.StringData(0) + ", " + record.StringData(1) + ", " + record.StringData(2));
if (record.IntegerData(2) != value)
{
WScript.StdOut.WriteLine(" - changing to " + value);
record.IntegerData(2) = value;
view.Modify(msiViewModifyUpdate,record);
}
else
WScript.StdOut.WriteLine(" - OK");
record = view.Fetch();
}
}
else
{
WScript.StdOut.WriteLine("Not found, so adding");
// There may be a better way to do this?
sql = "INSERT INTO Property (Property,Value) VALUES ('" + property + "','" + value + "')";
view = database.OpenView(sql);
view.Execute();
}
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
Then we can set the MSIUSEREALADMINDETECTION property to 1

Post a Comment

Previous Post Next Post