在 powershell 脚本中设置环境变量并从 .bat 文件读取它们

发布于 2025-01-09 00:35:20 字数 1872 浏览 0 评论 0原文

我有一个启动进程的 .bat 文件,我想通过使用 powershell 脚本执行一些自动化。 bat文件必须保留不依赖于我的原因。 .bat 文件包含一些环境变量的定义,例如:

@echo Opening solution.
set QTDIR=C:\Environment\Qt\5.15.2\msvc2019_64
set PHYSX_HEADER=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Include
set PHYSX_LIB_DEBUG=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Lib\vc16win64
set DDS_ROOT=C:\Environment\OpenDDS-DDS-3.16\
set ACE_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\
set TAO_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\TAO\

rem Setting doxygen
for /f "delims=" %%i in ('where doxygen') do set DOXYGEN_EXECUTABLE="%%i"

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" /Log "%USERPROFILE%\MyVSLog.xml" MySolution.sln

exit

这是因为不同的项目需要名称相同但内容不同的环境变量。

现在,我想在 powershell 脚本上下文中创建与在 .bat 文件中创建的环境变量相同的环境变量,以便编译器和其他需要定义它们的进程可以使用它们。

在powershell脚本中,我可以使用以下代码读取bat文件中存储的环境变量的名称和值(由于调试目的而冗长):

$startBatFile = "$rootPath/Start_Solution.bat"

# Read environment variables
Select-String '^set ([^=]*)=(.*)' $startBatFile | ForEach-Object {
  "object is $_"
  $splitted = $_.Line.Split("=")
  "splitted is $splitted"
  $nameSplitted = $splitted[0].Split(" ")
  $variableName = $nameSplitted[1]
  $variableValue = $splitted[1]
  "- Set env variable $variableName to value $variableValue"
  Set-Variable -Name "env:$variableName" -Value $variableValue
}

在循环中,我可以设置,例如,$variableNameQTDIR$variableValueC:\Environment\Qt\5.15.2\msvc2019_64

但我无法将它们设置为环境变量。我希望具有与手动设置它们相同的行为:

$env:MyEnvVariable = $someValue

但使用 env 似乎不适用于 Set-Variable。我无法直接分配它们,因为我想避免在多个位置定义路径,并且因为我应该能够在脚本中加载包含不同环境变量定义的不同 .bat 文件,因此它们不是固定的我无法直接在 powershell 代码中编写它们。

如何通过从 .bat 文件读取环境变量来在 powershell 脚本中设置环境变量?

I've a .bat file that starts a process, and I want to perform some automation by using a powershell script. The bat file must remain reasons that don't depend on me. The .bat file contains the definitions of some environment variable, something like:

@echo Opening solution.
set QTDIR=C:\Environment\Qt\5.15.2\msvc2019_64
set PHYSX_HEADER=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Include
set PHYSX_LIB_DEBUG=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Lib\vc16win64
set DDS_ROOT=C:\Environment\OpenDDS-DDS-3.16\
set ACE_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\
set TAO_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\TAO\

rem Setting doxygen
for /f "delims=" %%i in ('where doxygen') do set DOXYGEN_EXECUTABLE="%%i"

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" /Log "%USERPROFILE%\MyVSLog.xml" MySolution.sln

exit

This due to the fact that different projects needs env variables with same name but different content.

Now I want to create in the powershell script context the same enviornment variables that I create in the .bat file, so they can be used by compilers and other processes that needs them defined.

In the powershell script I'm able to read the name and the value of environemnts variables stored in the bat file, with following code (verbose due to debugging purposes):

$startBatFile = "$rootPath/Start_Solution.bat"

# Read environment variables
Select-String '^set ([^=]*)=(.*)' $startBatFile | ForEach-Object {
  "object is $_"
  $splitted = $_.Line.Split("=")
  "splitted is $splitted"
  $nameSplitted = $splitted[0].Split(" ")
  $variableName = $nameSplitted[1]
  $variableValue = $splitted[1]
  "- Set env variable $variableName to value $variableValue"
  Set-Variable -Name "env:$variableName" -Value $variableValue
}

In the loop I can set, for example, $variableName to QTDIR and $variableValue to C:\Environment\Qt\5.15.2\msvc2019_64.

But I cannot set them as environment variables. I'd like to have the same behaviour as setting them manually:

$env:MyEnvVariable = $someValue

but using env does not seem to work with Set-Variable. I cannot assign them directly because I'd like to avoid to have paths defined in more than one place, and because I should be able to load in the script different .bat files that contains diffferent definitions for environment variables, so they are not fixed and I cannot write them directly in the powershell code.

How can I set environment variables in powershell script by reading them from the .bat file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦醒时光 2025-01-16 00:35:20

使用 Set-Content,而不是 Set-Variable

# Note: Parameters -Path and -Value are implied.
Set-Content "env:$variableName" $variableValue

Set-Variable 仅适用于 PowerShell 自身的变量,不适用于环境变量。

PowerShell 通过提供程序模型,采用 Environment 提供程序的形式,公开 Env: 驱动器(尝试 Get-ChildItem Env:)。

使用逐字名称(例如$Env:USERNAME)引用环境变量的通常形式是命名空间变量表示法的一个实例,并且相当于 Get-Content 调用(例如 Get-Content Env:USERNAME),或者在分配值的情况下,Set-Content(如上所示);有关更多信息,请参阅此答案

由于您间接提供环境变量的名称 - 通过(常规)变量$variableValue的值 - 命名空间符号不是选项,并且需要显式的 Set-Content 调用。

Use Set-Content, not Set-Variable:

# Note: Parameters -Path and -Value are implied.
Set-Content "env:$variableName" $variableValue

Set-Variable is only intended for PowerShell's own variables, not for environment variables.

PowerShell exposes environment variables via the provider model, in the form of the Environment provider, which exposes the Env: drive (try Get-ChildItem Env:).

The usual form of referring to environment variables, with verbatim names (e.g. $Env:USERNAME) is an instance of namespace variable notation, and the equivalent of a Get-Content call (e.g. Get-Content Env:USERNAME) or, in the case of assigning a value, Set-Content (as shown above); see this answer for more information.

Since you're providing the name of your environment variables indirectly - via the value of (regular) variable $variableValue - namespace notation is not an option, and an explicit Set-Content call is required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文