MSBUILD可以在不重新启动Visual Studio的情况下接收新的“用户”级环境变量吗?

时间:2014-06-18 12:41:24

标签: powershell msbuild nuget

我有一个NuGet包,它在其Init.ps1文件中设置了一些PowerShell cmdlet,我希望他们能够做的一件事是设置环境变量,这些变量在Visual中传递给构建工作室。

在我的Init.ps1脚本中,我使用以下行:

[Environment]::SetEnvironmentVariable("MyVariable", $someValue, "User") 

...设置用户'级别环境变量,确定一个常规的过程'由于程序包管理器控制台与MSBuild处于不同的进程,因此级别变量无法正常工作。此外,在程序包管理器控制台中手动设置$env:MyVariable = "foo"不会将其值传递给MSBuild。

  • 在MSBuild中,常规$(MyVariable)未填充' foo'根据需要。
  • 如果我使用[Environment]::GetEnvironmentVariable('MyVariable'),通常让我以EnvironmentVariableTarget.User为目标的重载不可用。

目标是能够删除到Package Manager控制台,运行任意cmdlet并在构建期间将更改保留在属性中。需要重启,重启或重新加载解决方案的答案并非我所寻找的。

  • 我是否遗漏了有关环境变量的内容?
  • 是否有另一种简单的方法可以从Package Manager Console设置我忽略的构建属性(缺少使用EnvDTE或Microsoft.Build来手动编辑每个项目的csproj文件?

更新 - 进一步的发现:

  • 环境变量设置正确,我也可以从命令提示符回显它们。
  • 如果我完全重新启动Visual Studio,那么变量最终会到达MSBUILD,但随后不会对变量进行后续更改。

似乎Visual Studio正在缓存环境变量。有没有办法刷新'一个过程'环境变量?

2 个答案:

答案 0 :(得分:3)

在一天结束时,不,我无法在没有重启的情况下找到获取环境变量的方法。

最后,我通过使用单独的Properties.targets(任意名称)来存储我的变量'像这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
  <!-- Storage for global configuration properties -->
  <PropertyGroup>   
    <MyVariable1></MyVariable1>     
    <MyVariable2></MyVariable2>
  </PropertyGroup>
</Project>

并使用以下行将其导入我的构建脚本:

<Import Project="Properties.targets" />

然后,为了操作变量,我使用两个powershell函数,从Init.ps1传递$ toolsPath,并使用它来设置属性:

function SetPackageProperty($toolsPath, $name, $value) {
    $propertiesFile = [System.IO.Path]::Combine($toolsPath, "Properties.targets")
    $msbuild = New-Object -TypeName Microsoft.Build.Evaluation.Project -ArgumentList $propertiesFile
    $var = $msbuild.Xml.AddProperty($name, $value)
    $msbuild.Save()
    [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.UnloadProject($msbuild)
}

获得属性:

function GetPackageProperty($toolsPath, $name) {
    $msbuild = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($project.FullName) | Select-Object -First 1
    $propertiesFile = [System.IO.Path]::Combine($toolsPath, "Properties.targets")
    $msbuild = New-Object -TypeName Microsoft.Build.Evaluation.Project -ArgumentList $propertiesFile
    $var = $msbuild.Xml.Properties | Where-Object {$_.Name -eq $name} | Select-Object -First 1
    [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.UnloadProject($msbuild)
    return $var.Value   
}

您可以将Properties.targets导入到要使用属性的任何构建脚本中。

希望这有助于某人!

答案 1 :(得分:2)

  
      
  • 如果我使用[Environment] :: GetEnvironmentVariable('MyVariable'),通常让我以EnvironmentVariableTarget.User为目标的重载不可用。
  •   

你确定吗?

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Foo">
        <Exec Command="setx MyVariable Foo" />
        <Exec Command="echo 1. %MyVariable%" />
        <Exec Command="echo 2. $(MyVariable)" />
        <PropertyGroup>
            <MyVariable>$([System.Environment]::GetEnvironmentVariable('MyVariable', System.EnvironmentVariableTarget.User))</MyVariable>
        </PropertyGroup>
        <Message Text="3. $(MyVariable)" />
    </Target>
</Project>