我可以在InstallShield 2012的XML文件更改区域中获取项目输出app.config文件吗?

时间:2012-05-03 00:12:15

标签: app-config installshield installshield-2012

我需要将调试/测试App.config文件中的几个路径更改为最终用户计算机上的最终主页。通过Visual Studio编辑Installer项目时,我看到了XML File Changes选项,帮助表明我应该导入要更改的xml文件。

但是...

有没有办法导入XML文件的项目输出?如果我直接浏览文件本身,我必须使用Debug或Release配置文件,这似乎很烦人。否则我可以使用基础App.config但是如果在构建它们时应用了任何转换它们会丢失。

所以我只是只是浏览一个文件,或者我可以抓住"项目输出"不知怎的,我可以为.exe文件?

3 个答案:

答案 0 :(得分:1)

XML文件更改是相当薄弱的茶。 要执行您要查找的内容,您必须创建一个自定义操作,以加载.config文件并在InstallShield之外更新它。

如果您使用的是2012 C#Wizard项目类型,则选项应该是创建一个.rul来捕获After Move Data中的OnEnd()事件。从.rul通过UseDLL调用到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);
            }
        }
    }

答案 1 :(得分:1)

虽然看起来它应该可以工作,但Installshield无法正确地识别项目输出(经常错过依赖项,即使它们不适用也会复制合并模块),或者给你一种方法来处理项目输出中的单个文件。

关于使用项目输出的问题我打开了不少于5个错误,他们的解决方法始终是“手动添加文件”。

如果你刚开始使用安装盾牌,我建议你尝试另一种选择。如果你必须使用它,要么抱怨这不适用于他们的支持团队并使用建议的解决方法,直到他们将它们结合在一起。

这可能不是您问题的“答案”,但在处理本产品中的功能损坏时,希望能帮助您理解。

答案 2 :(得分:0)

您可以导入所需的任何文件(通过浏览),并在您喜欢的任何运行时位置对其进行更改。我建议你只需要做出改变所需的最低金额;毕竟它是XML文件更改视图。这样,对文件的大多数更新都不会导致或要求对XML文件更改设置进行任何更改,无论它包含在何处。