如何确保对C#项目中的配置文件所做的更改会导致重新生成DLL?
我在Visual Studio 2015中有一个C#DLL项目(a),其中有一个自定义配置文件,我希望将其复制到输出,因此“复制到输出目录”设置为“如果更新,则复制”。此DLL被同一解决方案中的另一个项目(B)引用。每当我重建项目B时,项目A中的配置文件都会复制到它的输出目录,正如我所希望的那样 问题是,如果我只修改配置文件,它不会被复制到输出中。我认为这是因为项目A的输出没有更改,所以MSBuild不需要将其复制到项目B的输出目录中 我发现的一个解决方法是将配置文件的内容类型设置为“Embedded Resource”,这样每当配置文件发生更改时都会重新生成项目A。这是可行的,但有点麻烦。有没有更好的方法可以在不将配置文件包含在DLL中的情况下获得相同的行为?而不是使用“更新时复制”您可以通过使用project B的project settings中的post-build event命令来实现这一点。只需设置一个xcopy命令,将web.config从project A目录复制到project B的build output文件夹中。有些生成参数有助于设置正确的目录,而不是硬编码所有目录名字 请看这篇文章:如何确保对C#项目中的配置文件所做的更改会导致重新生成DLL?,c#,build,msbuild,visual-studio-2015,C#,Build,Msbuild,Visual Studio 2015,我在Visual Studio 2015中有一个C#DLL项目(a),其中有一个自定义配置文件,我希望将其复制到输出,因此“复制到输出目录”设置为“如果更新,则复制”。此DLL被同一解决方案中的另一个项目(B)引用。每当我重建项目B时,项目A中的配置文件都会复制到它的输出目录,正如我所希望的那样 问题是,如果我只修改配置文件,它不会被复制到输出中。我认为这是因为项目A的输出没有更改,所以MSBuild不需要将其复制到项目B的输出目录中 我发现的一个解决方法是将配置文件的内容类型设置为“Embed
通常在使用DLL时,您不会配置DLL,而是在项目中使用DLL 为了解释,我们假设您有一个DLL,可以在两个可执行项目中重用它。项目B引用项目A,项目C引用项目A。在本例中,项目A是DLL,项目B和项目C是可执行文件。让我们进一步假设项目A使用配置设置,但项目B和项目C的实际值都需要不同 在这种情况下,您要做的是在exe B和exe C的应用程序配置中指定dll所需的设置。还要注意,部署应用程序时,配置可能会再次不同 为了说明如何在应用程序配置中包含DLL的配置,我创建了以下内容。最重要的是如何在最终的app.config中使用名称空间 类库
namespace ClassLibrary1
{
public class Class1
{
public string Message()
{
return Settings.Default.Message;
}
}
}
控制台应用程序
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new Class1().Message());
Console.WriteLine(Settings.Default.Message);
Console.ReadKey();
}
}
}
<?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="ConsoleApplication3.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="ClassLibrary1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<ConsoleApplication3.Properties.Settings>
<setting name="Message" serializeAs="String">
<value>Hello from application</value>
</setting>
</ConsoleApplication3.Properties.Settings>
<ClassLibrary1.Properties.Settings>
<setting name="Message" serializeAs="String">
<value>Hello from DLL</value>
</setting>
</ClassLibrary1.Properties.Settings>
</applicationSettings>
</configuration>
控制台应用程序的配置
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new Class1().Message());
Console.WriteLine(Settings.Default.Message);
Console.ReadKey();
}
}
}
<?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="ConsoleApplication3.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="ClassLibrary1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<ConsoleApplication3.Properties.Settings>
<setting name="Message" serializeAs="String">
<value>Hello from application</value>
</setting>
</ConsoleApplication3.Properties.Settings>
<ClassLibrary1.Properties.Settings>
<setting name="Message" serializeAs="String">
<value>Hello from DLL</value>
</setting>
</ClassLibrary1.Properties.Settings>
</applicationSettings>
</configuration>
你好,来自应用程序
你好,来自DLL
使用dll运行此应用程序将显示以下输出
Hello from DLL
Hello from application
我希望这会有所帮助。如果您使用VS 2015,您也可以使用所谓的共享项目,当您引用共享项目时,共享项目中包含的源代码文件将被复制并同步到引用项目。通过这种方式,您可以将您的配置文件同步到其他引用项目,甚至在构建之前 好吧,我想我已经想出了一个办法。在Microsoft.CSharp.Core.targets中定义了一个
CustomAdditionalCompileInputs
项目组,CoreComile
目标依赖于此。因此,我简单地添加了以下目标,以使CoreCompile依赖于所有具有构建操作的文件None
或Content
:
<Target Name="EnsureRecompiledOnConfigFileChanges" BeforeTargets="BeforeBuild">
<!-- Recompile the project if any items of type "None" or "Content" change in case some of them are config files for a DLL. -->
<ItemGroup>
<CustomAdditionalCompileInputs Include="@(None)" />
<CustomAdditionalCompileInputs Include="@(Content)" />
</ItemGroup>
</Target>
有一个选项“始终复制”,请尝试一下好吗?我不想使用“始终复制”,因为这会导致项目B一直被重建。我只希望在实际发生变化时重建它。我不会使用嵌入式资源。您也可以包含一个包含常量的静态类。您将如何重新定义目标部署中包含的资源中的内容?我理解这一点,但拥有公共设置(在引用项目之间共享)对我也很有用。如果您真的想重用设置,我将创建一个生成后步骤,使用XSLT更改项目文件的配置。另外,请查看并阅读Chris的答案。他还很好地解释了为什么您通常不重用配置。但他也解释了如何做到:)这可能可行,但需要手动列出引用项目A的所有项目中的所有配置文件。我认为将配置文件作为嵌入式资源比这更“干净”。如果您使用的是新的项目系统(如果您使用的是SDK样式的项目,那么您使用的是新的项目系统)然后,您应该将自定义输入添加到UpdateCheckInput
组,而不是CustomAdditionalCompileInputs
。