gpt4 book ai didi

environment-variables - MSBuild 无法查看从生成工作流设置的环境变量

转载 作者:行者123 更新时间:2023-12-02 02:11:52 26 4
gpt4 key购买 nike

这与 TFS 2010 构建系统有关。在我们的构建工作流程中,我们使用 System.Environment 类的 SetEnvironmentVariable 方法设置了几个环境变量。我已确认此环境变量已在构建服务器上正确设置,并且已设置为系统范围的环境变量。

问题是,当在此 WF 中调用 MSBuild 并编译解决方案时,我们尝试读取此环境变量的构建后事件失败,因为它们无法看到此环境变量。

有没有办法强制 MSBuild 重新加载环境变量或强制正在运行的 WF 重新加载环境变量?我怀疑即使 WF 创建了这个变量,它也不会刷新其环境状态,因此看不到该变量。此外,由于 WF 调用 MSBuild,它会将相同的环境状态传递给不包含此变量的 MSBuild。

更新

将以下代码粘贴到 Visual Studio 中并运行它。 SendMessageTimeOut 的延迟为 10 秒,请耐心等待。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace EnvironmentVarTest
{
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool
SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
out int lpdwResult
);

public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;


static void Main(string[] args)
{
Program p = new Program();
string environmentVariableValue = DateTime.Now.ToLongTimeString().Replace(":", String.Empty);
Console.WriteLine("On the CMD window that opens up after about 10 seconds, if you type %samplevar% and hit Enter, you should see: " + environmentVariableValue);
p.SetEnvironmentVariable(environmentVariableValue);
RefreshProcessVars();
p.ReadEnvironmentVariable();

p.StartCMD();
Console.ReadLine();
}

void SetEnvironmentVariable(string value)
{
System.Environment.SetEnvironmentVariable("samplevar", value, EnvironmentVariableTarget.Machine);

}

static void RefreshProcessVars()
{
int result;
bool callresult = SendMessageTimeout(
(System.IntPtr)HWND_BROADCAST,
WM_SETTINGCHANGE,
0,
"Environment",
SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
10000,
out result);

if (!callresult || result == 0)
{
int lasterror = Marshal.GetLastWin32Error();
Win32Exception winex = new Win32Exception(lasterror);
Console.WriteLine("Exception happened while calling SendMessageTimeOut. The exception message is " + winex.Message);
}
}
void ReadEnvironmentVariable()
{
var x = System.Environment.GetEnvironmentVariable("samplevar", EnvironmentVariableTarget.Machine);

}

void StartCMD()
{
Process.Start("cmd.exe");
}
}
}

最佳答案

不幸的是,因为 MSBuild 进程在启动时传递了环境变量的缓存版本,所以该进程的命令行功能将无法看到更新后的值。在我看来,最好的办法是在构建后事件中更改该变量,或者将值存储在可以从构建后事件中读取的介质中。

更新

好的,下面的语句(可以在 here 中找到)我认为解释了环境变量的位置以及为什么你没有得到MSBuild 中的更新版本。

By default, a child process inherits the environment variables of its parent process.

所以,两个人可以玩那个游戏,让我们广播已经发生的变化,看看它是否会为我们解决。下面是应该为您执行此操作的代码。

[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool
SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
out int lpdwResult
);

public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;

int result;
SendMessageTimeout(
(System.IntPtr)HWND_BROADCAST,
WM_SETTINGCHANGE,
0,
"Environment",
SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
SomeTimeoutValue,
out result);

关于environment-variables - MSBuild 无法查看从生成工作流设置的环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12371630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com