Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更改应用程序';s exe.config文件,当使用Windows Installer安装时_C#_.net_Windows Installer_Installation - Fatal编程技术网

C# 如何更改应用程序';s exe.config文件,当使用Windows Installer安装时

C# 如何更改应用程序';s exe.config文件,当使用Windows Installer安装时,c#,.net,windows-installer,installation,C#,.net,Windows Installer,Installation,我已经创建了一个Windows服务应用程序 我还为服务应用程序创建了一个Windows安装程序 在安装程序项目中,我添加了一个自定义屏幕,为用户提供了一个输入值的屏幕(右键单击安装项目->视图->用户界面->右键单击“开始”部分->添加对话框->文本框->确定) 我已将该属性作为参数添加到自定义操作中 我已将代码添加到: private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e) 并

我已经创建了一个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文件。

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

注意:截屏后,我还尝试将屏幕右上角的
访问修饰符
内部
更改为
公共
,结果仍然相同

生成的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文件的情况下将值写入applicationame.exe.config文件。

该类绝对是您想要的

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);
        }
    }
}

如果你不喜欢浪费时间重新发明轮子,你可以找到像AdvancedInstaller(免责声明:我在团队建设中工作)这样的工具,它可以为你做到这一点,而无需编写任何代码

这是一本书

还有更多关于此的文档:


可能还有其他类似于高级安装程序的工具可以做到这一点,但都是付费工具。这只是一个你的时间值多少的问题。

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

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

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


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

安装时需要更改的配置文件中的内容是什么?该服务监视特定文件夹并处理其中的文件。我希望用户能够在安装过程中进行设置谢谢!由于这是一个自动创建的配置文件,我实际上在寻找类似
ConfigurationManager
类的东西,它允许直接更新exe.config文件(不使用XML类),谢谢您的回复
System.Reflection.Assembly.getExecutionGassembly().Location
会返回正确的应用程序安装位置(我已将其写入随机文本文件并将其签出)。而且,这正是我在安装程序中添加参数的方式。我没有详细说明这一点,因为接受用户的参数可以很好地工作(同样,作为mentioend,我已经将参数写入了一个随机文本文件,并且它被签出)。问题是在将其写入应用程序的.exe.config文件时,潜在的问题是错误地传递它会导致文本文件工作,但安装程序类不会工作,因为它与一堆其他参数一起损坏,因为安装程序类接口中的隐藏解析器正试图收集5或6参数all/something=onething等。不管怎样,希望您正在取得进展。
System.Configuration.ConfigurationManager.AppSettings.Set("setting1", Context.Parameters["PathValue"]);
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);
        }
    }
}