XML 文件更改是相当弱的茶。要执行您正在寻找的内容,您必须创建一个自定义操作来加载 .config 文件并在 InstallShield 之外对其进行更新。
如果您使用的是 2012 C# Wizard 项目类型,则选项应该是创建一个 .rul,以在 After Move Data 中捕获 OnEnd() 事件。通过 UseDLL 从 .rul 调用到 dll 并调用一个方法,该方法接受配置的目标路径和将值更新到的值。
以下是我正在测试的代码...使用 C# Wizard 项目类型,我添加了以下 InstallScript 规则来调用 C# dll:
function OnEnd()
string basePath;
BOOL bResult;
string dllPath;
OBJECT oAppConfig;
begin
dllPath = TARGETDIR ^ APPCONFIG_DLL;
try
set oAppConfig = DotNetCoCreateObject(dllPath, "AppConfig.ConfigMgr", "");
catch
MessageBox("Error Loading" + dllPath + ": " + Err.Description, INFORMATION);
abort;
endcatch;
try
basePath = "C:\\Program Files (x86)\\MyCompany\\Config Test\\";
bResult = oAppConfig.ConfigureSettings(basePath + "appsettings.xml", basePath + "app.config", "someAppSection");
catch
MessageBox("Error calling ConfigureSettings " + dllPath + " " + Err.Number + " " + Err.Description, INFORMATION);
endcatch;
end;
C#测试代码: public bool ConfigureSettings(string configFilePath, string targetAppConfigPath, string targetAppName) { bool completed = true;
try
{
XmlDocument configFileDoc = new XmlDocument();
configFileDoc.Load(configFilePath);
string installerTargetFileDoc = targetAppConfigPath; // InstallShield's build process for Visual Studio solutions does not rename the app.config file - Awesome!
System.IO.FileInfo fi = new System.IO.FileInfo(installerTargetFileDoc);
if (fi.Exists == false) installerTargetFileDoc = "app.config";
XmlDocument targetAppConfigDoc = new XmlDocument();
targetAppConfigDoc.Load(installerTargetFileDoc);
// ensure all required keys exist in the target .config file
AddRequiredKeys(configFileDoc.SelectSingleNode("configuration/" + targetAppName + "/requiredKeys"), ref targetAppConfigDoc);
// loop through each key in the common section of the configuration file
AddKeyValues(configFileDoc.SelectSingleNode("configuration/common/appSettings"), ref targetAppConfigDoc);
// loop through each key in the app specific section of the configuration file - it will override the standard configuration
AddKeyValues(configFileDoc.SelectSingleNode("configuration/" + targetAppName + "/appSettings"), ref targetAppConfigDoc);
// save it off
targetAppConfigDoc.Save(targetAppConfigPath);
}
catch (Exception ex)
{
completed = false;
throw ex;
}
return completed;
}
private void AddKeyValues(XmlNode configAppNodeSet, ref XmlDocument targetAppConfigDoc)
{
foreach (XmlNode configNode in configAppNodeSet.SelectNodes("add"))
{
XmlNode targetNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings/add[@key='" + configNode.Attributes["key"].Value + "']");
if (targetNode != null)
{
targetNode.Attributes["value"].Value = configNode.Attributes["value"].Value;
}
}
}
private void AddRequiredKeys(XmlNode targetAppNodeSet, ref XmlDocument targetAppConfigDoc)
{
foreach (XmlNode targetNode in targetAppNodeSet.SelectNodes("key"))
{
// add the key if it doesn't already exist
XmlNode appNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings/add[@key='" + targetNode.Attributes["value"].Value + "']");
if (appNode == null)
{
appNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings");
XmlNode newAddNode = targetAppConfigDoc.CreateNode(XmlNodeType.Element, "add", null);
XmlAttribute newAddNodeKey = targetAppConfigDoc.CreateAttribute("key");
newAddNodeKey.Value = targetNode.Attributes["value"].Value;
XmlAttribute newAddNodeValue = targetAppConfigDoc.CreateAttribute("value");
newAddNodeValue.Value = "NotSet";
newAddNode.Attributes.Append(newAddNodeKey);
newAddNode.Attributes.Append(newAddNodeValue);
appNode.AppendChild(newAddNode);
}
}
}