【问题标题】:How to change an application's exe.config file when it is being installed using Windows Installer使用 Windows Installer 安装应用程序时如何更改应用程序的 exe.config 文件
【发布时间】:2016-05-23 23:46:05
【问题描述】:

我创建了一个 Windows 服务应用程序。

我还为服务应用程序创建了一个 Windows 安装程序。

在安装程序项目中,我添加了一个自定义屏幕,为用户提供输入值的屏幕(右键单击设置项目 -> 查看 -> 用户界面 -> 右键单击​​“开始”部分 -> 添加对话框 ->文本框 -> 好的)

我已将该属性作为参数添加到自定义操作中。

我已将代码添加到:

private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)

并且能够将使用安装过程输入的自定义值写入文本文件。

private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
    string path = @"c:\test\123.txt";

    if (!File.Exists(path))
    {
        File.Create(path).Dispose();
        using (TextWriter tw = new StreamWriter(path))
        {
            tw.WriteLine("The setting is: " + Context.Parameters["PathValue"]);
            tw.Close();
        }

    }

    else if (File.Exists(path))
    {
        using (TextWriter tw = new StreamWriter(path))
        {
            tw.WriteLine("The setting is: " + Context.Parameters["PathValue"]);
            tw.Close();
        }
    }
}

现在,我只想将值写入应用程序的 applicationame.exe.config 文件。

我已经使用“项目属性”窗口为服务创建了一个配置文件:

注意:截图后,我也尝试将屏幕右上角的Access ModifierInternal更改为Public,结果还是一样。

生成的applicationname.exe.config文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="WindowsService2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <applicationSettings>
        <WindowsService2.Properties.Settings>
            <setting name="setting1" serializeAs="String">
                <value>default111</value>
            </setting>
        </WindowsService2.Properties.Settings>
    </applicationSettings>
</configuration>

如何在不手动解析 XML 的情况下写入此内容?

请注意,由于某种原因,我的 applicationname.exe.config 文件的格式不是&lt;add key="setting1" value="default111" /&gt;

另外,我的 bin 文件夹中没有 app.config 文件。我只有 applicationname.exe.config。

我已经试过了。但这不会更新 application.exe.config 文件,也不会引发任何错误。

private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
{

    Configuration config = ConfigurationManager.OpenExeConfiguration(@System.Reflection.Assembly.GetExecutingAssembly().Location);
    string value = System.Configuration.ConfigurationManager.AppSettings["setting1"];
    System.Configuration.ConfigurationManager.AppSettings["setting1"] = Context.Parameters["PathValue"];
    config.Save(ConfigurationSaveMode.Modified);

}

我也尝试了以下方法,但没有成功(但没有错误消息):

System.Configuration.ConfigurationManager.AppSettings.Set("setting1", Context.Parameters["PathValue"]);

请帮我弄清楚如何在不解析 XML 文件的情况下将值写入 applicationame.exe.config 文件。

【问题讨论】:

  • 您在配置文件中放置了哪些需要在安装时更改的内容?
  • 服务监控特定文件夹并处理其中的文件。我希望用户能够在安装过程中进行设置

标签: c# .net windows-installer installation


【解决方案1】:

总体问题是您没有在应用程序环境中运行。您的代码是通过您安装的程序集的反射从 msiexec.exe 调用的,并且可能在 SYSTEM 帐户下运行。这就是为什么它不只是工作。

另一个可能的问题是您的 Bin 文件夹屏幕截图无关紧要。 Bin 文件夹与文件的安装位置(很可能在 Program Files 中)之间没有任何联系,也没有证据表明您在安装中包含了配置文件。没有规则“Bin 文件夹中的所有内容都安装到系统中”。因此,您的目标应用程序文件夹的屏幕截图对于查看配置文件是否存在更有用 - 您的自定义操作将在所有文件安装后运行,因此请查看那里。

也不清楚(至少对我来说)GetExecutionAssembly().Location 将返回正确的值。调用托管代码自定义操作时使用反射加载和实例化程序集,并且位置文档暗示 LoadByte 程序集(可能在加载代码中使用)导致空字符串。因此,可能值得尝试不同的方法,例如 GetExecutingAssembly().GetName().CodeBase。

此外,需要非常小心地将路径作为参数添加到安装程序类,并且您的帖子不会显示您所做的事情。如果您的属性名称是 MYPATH(并且它必须是大写),那么您的参数需要是 /PathValue="[MYPROP]\" 并带有尾随反斜杠。有一堆参数传递到安装程序类方法(包括您的程序集名称)中,反斜杠用于阻止整个参数列表变得不连贯。您不会在其他自定义操作中遇到此问题,因为您的是唯一传递的参数。

【讨论】:

  • 感谢您的回复! System.Reflection.Assembly.GetExecutingAssembly().Location 确实 返回应用程序安装的正确位置(我已将其写入随机文本文件并已签出)。而且,这就是我将参数添加到安装程序的确切方式。我没有详细说明这一点,因为如上所述,接受用户的参数可以正常工作(再次提及,我已将参数写入随机文本文件并进行检查)。问题在于将其写入应用程序的 .exe.config 文件
  • 潜在的问题是错误地传递它会导致您的文本文件工作,但安装程序类将无法工作,因为它与一堆其他参数混在一起,因为安装程序类中的隐藏解析器interface 正在尝试收集 5 或 6 个参数 all /something=onething 等。无论如何,希望你正在取得进展。
【解决方案2】:

XmlDocument 类绝对是您正在寻找的。​​p>

using System;
using System.Xml;

namespace ConfigModifier
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string fileName = @"C:\Some\entered\path\appName.exe.config";
            xmlDoc.Load(fileName);
            xmlDoc["configuration"]["applicationSettings"]["WindowsService2.Properties.Settings"]["setting"]["value"].InnerText = "My New Value";
            xmlDoc.Save(fileName);
            Console.ReadKey(true);
        }
    }
}

【讨论】:

  • 谢谢!由于这是一个自动创建的配置文件,我实际上是在寻找诸如 ConfigurationManager 类之类的东西,它允许直接更新 exe.config 文件(不使用 XML 类)
【解决方案3】:

如果您不喜欢在重新发明轮子上浪费时间,您可以找到 Advanced Installer 等工具(免责声明:我在团队构建它)为您完成此任务,而无需编写任何代码代码。

这是video that show the XML updater from Advanced Installer

还有更多关于此的文档:

XML updater documentation

XML updater example for web.config file

可能还有其他类似于 Advanced Installer 的工具可以执行此操作,但都是付费工具。这只是你的时间价值多少的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2018-09-13
    相关资源
    最近更新 更多