我正在编写一个游戏开发IDE,用于创建和编译.NET项目(过去几年我一直在研究),并且我正在更新它以生成输出,不仅适用于Windows / Visual Studio ,也适用于Linux / MonoDevelop(一个非常简单的.NET进程,但仍需要一些调整)。
作为其中的一部分,我发现有必要开始生成app.config文件作为其中的一部分,以使用< dllmap>将依赖的DLL名称映射到Linux依赖项名称。元素。我很担心谁负责将app.config文件复制到输出名称app.exe.config。在Visual Studio项目中,app.config的Build Action通常设置为“None”,其设置表明它不会被复制到任何地方,但是当Visual Studio编译项目时它会生成app.exe.config(虽然我有时发现这是不可靠的)。当我使用MSBuild构建IDE生成的解决方案文件(用于调试目的)时,MSBuild将app.config复制到app.exe.config。但是当我使用CSharpCodeProvider.CompileAssemblyFromFile编译项目时(它自然)不喜欢将配置文件作为源代码包含(“app.config(1,1):错误CS0116:命名空间不直接包含诸如字段之类的成员或方法“),当然,当我不将它作为输入包括它时,它不会将它复制到输出。我是否有责任将app.config单独复制到app.exe.config,还是有更标准的方法来执行此操作?
第一个* .config文件是否硬连线?在我的IDE中,可以想象app.config文件将被重命名或添加另一个(就像在Visual Studio中一样)。我觉得IDE对配置文件有这个秘密行为似乎很奇怪(我认为MonoDevelop在这方面表现相似,因为我找不到配置文件的特殊操作)。我不知道它甚至会选择这个秘密行动适用的文件。
答案 0 :(得分:8)
C#编译器根本不关心配置文件。构建环境(MSBuild和VS)将负责自己复制该文件。
答案 1 :(得分:7)
订单:
msbuild / xbuild还允许您通过设置$(AppConfig)属性来覆盖它。
答案 2 :(得分:1)
我认为MSBuild负责复制。如果您要挖掘库存.target文件,那么您可能会找到相应的指令。 VS本身不会复制。
答案 3 :(得分:1)
另请注意,Visual Studio会验证配置文件。
答案 4 :(得分:1)
稍微更具技术性的答案 - 您的项目通过csproj文件中的此键引用Microsoft.CSharp.targets
:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
此文件将解析为c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets
,具体取决于您的框架版本。
在其内部,您可以使用此部分来完成工作:
<!--
============================================================
_CopyAppConfigFile
Copy the application config file.
============================================================
-->
<Target
Name="_CopyAppConfigFile"
Condition=" '@(AppConfigWithTargetPath)' != '' "
Inputs="@(AppConfigWithTargetPath)"
Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
<!--
Copy the application's .config file, if any.
Not using SkipUnchangedFiles="true" because the application may want to change
the app.config and not have an incremental build replace it.
-->
<Copy
SourceFiles="@(AppConfigWithTargetPath)"
DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)"
>
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
App.Config文件似乎是作为一个环境变量传递的(预计它会存在,但是谁设置它,我不知道):
<ItemGroup>
<AppConfigWithTargetPath Include="$(AppConfig)" Condition="'$(AppConfig)'!=''">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
修改:有关如何选择app.config,请参阅此回答 - https://stackoverflow.com/a/40293508/492336。
app.config的处理很特殊,按名称处理,构建过程将按照以下顺序选择app.config文件:
- 选择主项目中设置的值$(AppConfig)。
- 在与项目相同的文件夹中选择@(无)App.Config。
- 在与项目相同的文件夹中选择@(内容)App.Config。
- 在项目的任何子文件夹中选择@(无)App.Config。
- 在项目的任何子文件夹中选择@(内容)App.Config。