Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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# 如何在运行时读取给定项目中的MSBuild属性?_C#_Parameters_Msbuild_.net 4.5 - Fatal编程技术网

C# 如何在运行时读取给定项目中的MSBuild属性?

C# 如何在运行时读取给定项目中的MSBuild属性?,c#,parameters,msbuild,.net-4.5,C#,Parameters,Msbuild,.net 4.5,我想在单元测试中访问MSBuild变量,单元测试是.NET 4.5类库项目(classic csproj),但我找不到任何讨论如何将值从MSBuild传递到执行上下文的文章 我考虑在编译期间设置一个环境变量,然后在执行期间读取该环境变量,但这似乎需要一个自定义任务来设置环境变量值,我有点担心变量的范围(理想情况下,我只希望它可用于当前正在执行的项目,而不是全局) 在运行时从DLL项目内部读取MSBuild属性是否有已知的解决方案?MSBuild属性是否可以在执行过程中以某种方式“作为参数传递”?

我想在单元测试中访问MSBuild变量,单元测试是.NET 4.5类库项目(classic csproj),但我找不到任何讨论如何将值从MSBuild传递到执行上下文的文章

我考虑在编译期间设置一个环境变量,然后在执行期间读取该环境变量,但这似乎需要一个自定义任务来设置环境变量值,我有点担心变量的范围(理想情况下,我只希望它可用于当前正在执行的项目,而不是全局)


在运行时从DLL项目内部读取MSBuild属性是否有已知的解决方案?MSBuild属性是否可以在执行过程中以某种方式“作为参数传递”?

我认为您有两个选项:

  • 使用环境变量,如您已经建议的那样。可能需要自定义任务来执行,但它是,在您的部分上没有任何额外的程序集。所需的全局可见性可能是一个棘手的问题;例如,在CI机器上并行构建。
  • 在构建过程中编写一个代码片段,并将其包含到生成的程序集中(类似于您在注释中建议的您已经在下面找到的内容)
  • 在生成期间编写一个包含反映所需MSBuild属性的设置的文件(甚至是app.config);在测试运行期间读取这些设置
(顺便说一句,没有什么意义的是,尝试在运行时(使用框架)再次读取MSBuild项目文件。这一次,首先需要做大量的工作,但收获甚微。 更重要的是,根据属性的复杂性和依赖性,您最有可能需要确保调用MSBuild库时使用的属性与实际生成过程中存在的属性相同。可以说,这可能会让您回到最初的版本。)

最后两个选项最适合,因为它们具有相同的特性:它们的范围仅限于您当前拥有的构建/测试运行(即,您可以在没有干扰的情况下并行运行构建)

我可能会选择第三种,因为这似乎是最容易实现的

事实上,我在一个更大的项目上做过这样的工作。基本上,我们有不同的环境(数据库连接字符串等),并且会选择这些环境 作为构建后步骤,基本上将特定的
myenv.config
复制到
default.config

测试只会查找名为
default.config
的文件,并选择其中设置的任何设置。

我最终通过使用默认情况下在.Net核心项目中使用的相同代码生成任务使其工作。唯一的区别是我必须在csproj文件中手动添加
目标
s代码创建不是框架项目的标准:

<Target Name="BeforeBuild">
  <ItemGroup>
    <AssemblyAttributes Include="MyProject.SolutionFileAttribute">
      <_Parameter1>$(SolutionPath)</_Parameter1>
    </AssemblyAttributes>
  </ItemGroup>
  <WriteCodeFragment AssemblyAttributes="@(AssemblyAttributes)" Language="C#" OutputDirectory="$(IntermediateOutputPath)" OutputFile="SolutionInfo.cs">
    <Output TaskParameter="OutputFile" ItemName="Compile" />
    <Output TaskParameter="OutputFile" ItemName="FileWrites" />
  </WriteCodeFragment>
</Target>

这非常有效,并允许我避免对解决方案文件进行任何硬编码搜索。

ConditionalAttribute有什么问题?不确定
ConditionalAttribute
对我的案例@CJohnson有何帮助。它只允许您检查常量键(如
DEBUG
RELEASE
),我希望MSBuild中的实际值是动态的。虽然我的问题被标记为重复,但链接的答案仅为.Net Core提供答案,而不是为.Net Framework提供答案。我能够通过使其在.Net Framework中工作。@julealgon请将此类详细信息添加到问题中,很容易忽略标记。是否希望(我/我们)要删除重复标记并可能添加您自己的答案?@MartinUllrich我现在添加了.Net4.5标记。我认为您需要在另一个线程上更新您的答案,以包含在.Net中解决此问题所需的位,或者您可以将其取消标记为重复。我可以自己添加答案。
Assembly
    .GetExecutingAssembly()
    .GetCustomAttribute<SolutionFileAttribute>()
    .SolutionFile