问题
I'm writing a WIX script.
I have a custom-action that adds rows dynamically to the Registry table:
function AddRegistry()
{
var registryView = Session.Database.OpenView("SELECT * FROM Registry");
registryView.Execute();
var record = Session.Installer.CreateRecord(6);
record.StringData(1) = "Unique123456";
record.IntegerData(2) = 2;
record.StringData(3) = "Software";
record.StringData(4) = "my_registry_string";
record.StringData(5) = "value";
record.StringData(6) = "MyComponent";
registryView.Modify(7, record); //InsertTemporary
registryView.Close();
return 1; //Ok
}
The custom-action is scheduled to run as "immediate" and before the "WriteRegistryValues" action:
<CustomAction Id="AddRegistry" BinaryKey="CustomActionJS"
JScriptCall="AddRegistry"
Execute="immediate" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="AddRegistry" Before="WriteRegistryValues" />
<Custom Action="CheckRegistry" After="WriteRegistryValues" />
...
</InstallExecuteSequence>
I've added a 2nd custom-action that enumerates the Registry table, and shows all the entries just find (fixed and temporary).
However, when the WriteRegistryValues is being executed (it is deferred, as far as I understand), it only writes the fixed entries. My dynamic entries are ignored, and not added to the registry.
A fixed Registry entry to the same registry path works fine:
<Component Id="MyComponent">
<RegistryValue Id="Unique11111" Root="HKLM" Key="Software"
Name="my_fixed_value" Value="my_value"
Action="write" Type="string"/>
</Component>
Any idea what I'm doing wrong?
回答1:
I do it this way using a generic method: (Example is in C# using DTF as ActiveScript Custom Actions such as JScript/VBScript are not a best practice for MSI )
private static void InsertRecord(Session session, string tableName, Object[] objects)
{
Database db = session.Database;
string sqlInsertSring = db.Tables[tableName].SqlInsertString + " TEMPORARY";
session.Log("SqlInsertString is {0}", sqlInsertSring);
View view = db.OpenView(sqlInsertSring);
view.Execute(new Record(objects));
view.Close();
}
Using it looks like
object[] fields = new object[] { .... };
InsertRecord(session, "TableName", fields);
回答2:
OK!
I figured it our - the CA that adds rows to the Registry table must run before InstallValidate (which runs before WriteRegistryValues)
so changing
<Custom Action="AddRegistry" Before="WriteRegistryValues" />
to
<Custom Action="AddRegistry" Before="InstallValidate" />
solved the problem
来源:https://stackoverflow.com/questions/11970453/temporary-rows-added-by-custom-action-are-ignored-by-writeregistryvalues