在 powershell 脚本中设置环境变量并从 .bat 文件读取它们
我有一个启动进程的 .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
}
在循环中,我可以设置,例如,$variableName
到 QTDIR
和 $variableValue
到 C:\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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用
Set-Content
,而不是Set-Variable
: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
, notSet-Variable
: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 theEnv:
drive (tryGet-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 aGet-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 explicitSet-Content
call is required.