如何在MSBuild中获取当前操作系统?

25

我有一个使用Visual Studio 2017创建的.NET Core 1.1控制台项目。 构建完项目后,我需要运行一个PowerShell脚本,因此我将以下代码添加到MyProject.csproj文件中:

<Target Name="PostcompileScript" AfterTargets="Build">
    <Exec Command="execute-tasks.ps1" />
</Target>

现在我需要在Linux环境中构建项目,我需要指示MSBuild在Linux运行时运行execute-tasks.sh而不是execute-tasks.ps1

我相信可以通过Condition属性实现,但是否有一个MSBuild变量保存操作系统名称?

3个回答

35
变量是$(OS),通常会检查是否为Windows_NT
<Exec Command="./foo.sh" Condition=" '$(OS)' != 'Windows_NT' " />

7
OS指令的官方文档在哪里?还有哪些其他的OS选项? - Shimmy Weitzhandler
1
这里有一个关于可以在官方MSBuild存储库中返回的值的问题讨论 - https://github.com/Microsoft/msbuild/issues/539 - 我没有调查最终结果是什么,但显然可能的值是Windows_NT,Unix和可能的OSX(Github中问题的内容)。 - Otto G
这里由msbuild作者@rainersigwald记录:https://github.com/dotnet/msbuild/issues/2468#issuecomment-324694593 - M.Hassan

32

使用其他回答中所记录的$(OS)可以区分Windows_NTUnix(包括Linux和macOS),但无法区分不同的类Unix系统。如果您正在使用MSBuild 15.3或更高版本(这是非常可能的),您可以考虑使用[MSBuild]::IsOsPlatform()

<Exec Command="./foo.sh" Condition="$([MSBuild]::IsOSPlatform('Linux'))" />

参数可以是任何OsPlatform成员的名称。


1
很好,这对我有用(使用Windows而不是Linux)。 - BrainSlugs83
1
甚至有 $([MSBuild]::IsOSUnixLike()) 作为上述内容的快捷方式。 - Oliver
这在 Docker 容器中不起作用。 - Michael Brown

0

您可以像这样使用目标。在MSBUILD中,操作系统版本似乎不是环境变量。

 <Target Name="AfterBuild">
          <Exec Command="foo.exe arg1 arg2" Condition=" '$(OS)' == 'Windows_NT' " />
 </Target>

另一个例子是,这可能会很繁琐。

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="OSVersion" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OsVersion>$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion@CurrentVersion).$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion@CurrentBuildNumber)</OsVersion>
  </PropertyGroup>
  <Target Name="OSVersion">
    <Message Text="Version: $(OsVersion)" />
  </Target>
</Project>

2
仅仅是注册表访问在*nix系统上并不那么有用。即使在Windows上运行,它也只能在使用完整框架的MSBuild时才有效,而不能在随CLI一起提供的.NET Core版本中使用。 - Martin Ullrich
好的,我不知道 .net core 的版本。 - danglingpointer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接