如何在 VS2010 C# 控制台应用程序中将我的 App.config 编译到我的 exe 中?

Posted

技术标签:

【中文标题】如何在 VS2010 C# 控制台应用程序中将我的 App.config 编译到我的 exe 中?【英文标题】:How do I compile my App.config into my exe in a VS2010 C# console app? 【发布时间】:2011-06-02 22:34:39 【问题描述】:

我正在使用 c# 在 Visual Studio 2010 中创建一个控制台应用程序。我希望这个应用程序是独立的,因为你所需要的只是 exe,你可以从任何地方运行它。我还想使用 app.config 来存储连接字符串等。

我的问题是我似乎无法弄清楚如何将该 app.config 数据包含到已编译的 exe 中。我确实看到它创建了 appname.exe.config,但我不希望人们在获取应用程序时不必担心获取两个单独的文件。

我所做的谷歌搜索都没有提出任何结果。这甚至可能吗?

【问题讨论】:

Configuration File as Embedded Resource的可能重复 想一想。如果可能,您的用户将无法再更改连接字符串。打败了拥有一个的点。单个文件从来都不是问题,它被称为 setup.exe Re: 重复的,那个没有出现在我的搜索中。这太糟糕了,因为它确实回答了我的问题。虽然我不得不说,硬编码应用程序设置而不是方便的配置文件让我感到不满意。我猜这是我的网络程序员 搜索这个问题会返回很多“你这个白痴你不想这样做”,而实际上“是的,我确实想这样做,因为我的 WCF 配置在 app.config 中更容易,我不希望用户更改它”。此外,在普通用户的计算机上,他们隐藏了已知的文件扩展名,因此他们看到“appname.exe”并双击它,但这实际上是隐藏扩展名的 appname.exe.config。如果您安装它并在他们的桌面上放置一个快捷方式,这不是问题,但我真的必须为每个我想给别人的一次性程序创建一个安装程序来避免这种情况吗? WCF 至少有一个在代码中配置的选项,但是一些依赖程序集甚至 .net 框架的东西需要在应用程序配置中输入......我没有选择改变这种行为,用户不需要更改这些值......所以想要以某种方式嵌入应用程序配置并不是“愚蠢” 【参考方案1】:

以一个winform应用程序为例,在编译过程中,会随着输出的EXE文件生成一个文件'xxx.EXE.config'。它将包含“app.config”设置。也分发这个。

【讨论】:

-1 -- 这是我特别想避免的。如何避免这样做是我的全部问题。我什至说——“我确实看到它创建了 appname.exe.config,但我不希望人们担心抓取两个单独的文件......”【参考方案2】:

最好的解决方法是在应用程序启动时自己创建它。

    将 App.Config 添加为资源,将其重命名为“App_Config” 检查配置文件是否存在 如果没有,请写入默认 .config 文件

示例代码:

程序.cs

    [STAThread]
    static void Main()
    
        CreateConfigIfNotExists();
    

    private static void CreateConfigIfNotExists()
    
        string configFile = string.Format("0.config", Application.ExecutablePath);

        if (!File.Exists(configFile))
        
            File.WriteAllText(configFile, Resources.App_Config);
        
    

请记住,它只会在构建时写入您当前的配置。当您部署新版本时,它不会自动更新。它将在构建时包含配置。但这可能就足够了:)

【讨论】:

一些用例的不错的解决方案。但是,安装程序通常以管理员权限运行,并且可以安装在 C:\Program Files 下。应用程序本身在没有管理员权限的情况下运行,因此无法写入安装 EXE 的文件夹(例如 C:\ Program Files 下)。【参考方案3】:

IL Merge 有很多问题,wpf 可执行文件也很慢。 我最终使用 Cosura.Fody https://github.com/Fody/Costura 并使用命令行参数来传递我的应用程序配置值。 还使用 iexpress http://en.wikipedia.org/wiki/IExpress 创建最终的可执行文件,将命令行 args 和 exe 合并在一起

【讨论】:

【参考方案4】:

就像人们在这里所说的那样,配置文件的全部意义在于修改应用程序之外的一些设置。您可以硬编码或使用常量,但如果您愿意,也可以在 Windows 中使用注册表。这样您就可以对应用程序进行更改,而仍然只有一个 exe 文件。

代码项目有一些关于从注册表读取、写入和删除的好信息。 http://www.codeproject.com/KB/system/modifyregistry.aspx 但是在编辑注册表时要小心。很多应用程序都依赖于它,所以如果你做错了什么,你可能会破坏一些设置。我建议先阅读,然后再做。

public string Read(string KeyName)  
RegistryKey rk = baseRegistryKey;
// Open a subKey as read-only

RegistryKey sk1 = rk.OpenSubKey(subKey);
// If the RegistrySubKey doesn't exist -> (null)

if ( sk1 == null )

    return null;

else

    try 
    
        // If the RegistryKey exists I get its value
        // or null is returned.
        return (string)sk1.GetValue(KeyName.ToUpper());
    
    catch (Exception e)
    
        // AAAAAAAAAAARGH, an error!
        ShowErrorMessage(e, "Reading registry " + KeyName.ToUpper());
        return null;
    
  


public bool Write(string KeyName, object Value)  
  try
  
      // Setting
      RegistryKey rk = baseRegistryKey ;
      // I have to use CreateSubKey 
      // (create or open it if already exits), 
      // 'cause OpenSubKey open a subKey as read-only
      RegistryKey sk1 = rk.CreateSubKey(subKey);
      // Save the value
      sk1.SetValue(KeyName.ToUpper(), Value);
      return true;
  
  catch (Exception e) 
        // AAAAAAAAAAARGH, an error!
        ShowErrorMessage(e, "Writing registry " + KeyName.ToUpper());
        return false;
    
      

public bool DeleteKey(string KeyName)  
  try
  
      // Setting
      RegistryKey rk = baseRegistryKey ;
      RegistryKey sk1 = rk.CreateSubKey(subKey);
      // If the RegistrySubKey doesn't exists -> (true)
      if ( sk1 == null )
          return true;
      else
          sk1.DeleteValue(KeyName);
      return true;
  
  catch (Exception e)
  
      // AAAAAAAAAAARGH, an error!
      ShowErrorMessage(e, "Deleting SubKey " + subKey);
      return false;
  

当然,这只适用于 Windows。我假设您使用的是 Visual Studio,因此您可能使用的是 Windows。

编码愉快,祝你好运!

【讨论】:

【参考方案5】:

正如其他人所指出的,配置文件背后的想法是避免硬编码值。

作为替代方案,您可以编写一个自定义配置部分,其中每个元素都是可选的并具有默认值。这样,任何可以使用默认设置的人都不需要配置文件。但如果他们需要覆盖默认值,他们可以提供一个。

(抱歉,只是有点头脑风暴。我没有可用的示例。)

【讨论】:

不幸的是,Microsoft (ab) 将此文件用于配置以外的其他用途。也就是说,它用于强制 .NET 4.5 应用程序拒绝在早期版本的 .NET 上运行。 Bass-ackwards 使这个用户可配置(同时也使单 exe 应用程序不可能),不是吗?【参考方案6】:

我可以看到你的意图,但答案可能比你想要的要复杂一些。

    将 app.config 设为嵌入式资源。 手动解析 app.config 以获取 default 应用设置/连接字符串/等 仍然查找 app.config 并使用 app.config 值覆盖您之前读取的默认值

这样你就有了一些合理的默认值,你不必将它们作为常量与 app.config 分开,你可以将你的应用程序作为一个 exe 运行,你仍然可以在运行时通过添加回应用程序配置。

要记住的一件事是,从资源中读取 app.config 不会获得与普通 app.config 相同的行为。您基本上是在阅读并手动使用它。

【讨论】:

呃,是的,这里的想法让事情变得更容易,而不是更难。看起来我最好在我的代码中创建一个设置对象。【参考方案7】:

您的意思是您需要将其作为资源添加到 exe 中?好吧,首先你不能,app.config 是基于文件而不是基于资源的。

另一方面,配置文件的唯一要点是您可以更改它。否则只需硬编码或使用常量。

【讨论】:

【参考方案8】:

你不能。此类配置文件的一半意义在于允许在应用程序本身之外更改应用程序的配置。

您只需修改您的程序,使其不依赖于应用配置文件——最简单的方法是将配置中的值粘贴到只读全局变量中。

【讨论】:

我想我错过了配置文件的重点。我将不得不硬设置它们。 虽然 +1,但问题在于工具将某些内容放入 app.config,而不是您(例如,当您添加对 Web 服务的引用时)。用户绝对不能触摸它,但它必须以单独的文件传送。愚蠢的奖励:常规的应用程序设置,包括连接字符串,确实嵌入到了 exe 中——你可以单独发送 exe,它会连接到数据库。但是 Web 服务引用的设置不会被嵌入,一旦你引用了一个,你必须分发.config。这只是愚蠢的。 当您需要 app.config 的唯一原因是确保您的程序拒绝在 .NET 4.0 上运行时,情况会更糟 - 因为由于某种原因,Microsoft 无法在组装本身... 另一个糟糕的 app.config 设置示例:启用 useLegacyJit,因为您有代码 like this,由于 RyuJIT 错误,该代码至今在 Win10 上崩溃。想要作为单个 exe 发布的程序无法访问该解决方法,这在任何意义上都不是用户设置。【参考方案9】:

请在上一篇文章中给出第一个答案 - Configuration File as Embedded Resource

【讨论】:

【参考方案10】:

通常,您不希望这样做,因为您的 app.config 提供了一种可以在运行时完成配置的机制。至于你的具体目标(在你的代码之外维护配置,但让它遵循二进制文件),你有几个选择:

动态创建配置文件 将设置存储在注册表中 将设置存储为控制台应用程序中的资源字符串

我相信还有其他更有创意的选择。我的建议是第二种选择。首次启动应用程序时,创建必要的键并从可执行文件中设置它们的默认值。这样,如果您以后需要进行任何调试,您只需运行 regedit 并进行任何必要的更改,而无需重新编译。

【讨论】:

我希望这件事完全独立,所以我想我会不理会注册表。看起来您的选项 3 最适合我的目的。

以上是关于如何在 VS2010 C# 控制台应用程序中将我的 App.config 编译到我的 exe 中?的主要内容,如果未能解决你的问题,请参考以下文章

在 VS2010 中将 FSharpx(来自 NuGet)与 F# 2.0 一起使用

如何在 C# 中将文本提取/插入到 RTF 字符串中

C# VS2010 Express:程序在IDE中运行,但不是exe,为啥? [关闭]

在VS2010中创建并引用dll(C#)

Sharepoint 2010通过wsp将控制注册为安全

无法在 VS 2010 中创建 UML C# 类图