如何更改 csproj 文件中的 Exec 任务生成其临时 exec.cmd 文件的文件夹?

How can I change the folder that Exec tasks in a csproj file generates its temporary exec.cmd files in?

我有一个包含一些 Exec 节点的 .NET 6 项目,这些命令失败是因为(如在 this discussion on the msbuild repo 中)生成的 tmp<blah>.exec.cmd 文件的路径不是已列入白名单。

其中建议的修复是

The location of this file is controlled by the environment variable TEMP. Can you set that to a custom value before invoking MSBuild?

我确定这会奏效 - 但我不知道该怎么做。根据 this question(适用于 C++ 而不是 C#,但这是我能找到的最好的),您可以在同一个节点中使用 EnvironmentVariables="<blah>",但文件仍然在 %LOCALAPPDATA% 中生成,尽管我尝试这样做将 TEMP 设置为其他内容。下面是一个失败的例子——我做错了什么?

<Target Name="ToolRestore" BeforeTargets="PreBuildEvent">
  <Exec Command="dotnet tool restore" StandardOutputImportance="high" EnvironmentVariables="TEMP=C:\MSBuildTemp" />
</Target>

理想情况下,答案应该在 Visual Studio 和 dotnet build/test/publish 中对 building/debugging 有效。更好的方法是使 TEMP 的值对每个用户可变,但这不是必需的。

根据code for the Exec task it does use the standard GetTempPath function, which means it really should react to user-level environment variables. However that function is documented喜欢:

This method checks for the existence of environment variables in the following order and uses the first path found:

The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
...

因此您找到的建议修复并不完全正确:您可能需要 TMP 而不是 TEMP。事实上,在我的机器上我设置了 TMP 并且 msbuild 将它用于它的临时批处理文件,可以使用打印批处理文件路径的目标看到 Exec 使用:

<Target Name="TempTest">
  <Exec Command="echo %~dp0"/>
</Target>

运行 在 cmd.exe:

>set TMP=c:\temp

>msbuild temptest.proj /t:TempTest /v:m /nologo
  c:\temp\

>set TMP=c:\Users

>msbuild temptest.proj /t:TempTest /v:m /nologo
temptest.proj(7,5): error MSB6003: The specified task executable "
cmd.exe" could not be run. Failed to create a temporary file. Temporary files folder is full or its path is incorrect.
Access to the path 'c:\Users\tmpb31f9faffaab49e9b3bd5479a6823550.exec.cmd' is denied.