在批处理文件中增加一个全局环境变量

问题描述 投票:0回答:2

我使用 setx 在我的批处理文件列表中设置一个全局计数器变量,这些文件在 parallel 中运行。 我这样设置第一个计数器:

setx counter 1

但是如何在另一个批处理文件中增加这个变量呢?我尝试了以下操作,但没有成功,它在计数器中设置了“%counter%+1”:

setx counter %counter%+1
windows batch-file cmd command-line environment-variables
2个回答
0
投票

我建议先阅读我对这个问题的长篇回答:“X不被识别为内部或外部命令、可操作程序或批处理文件”的原因是什么?章节B)描述了持久化的存储位置存储的环境变量。 F)章节以一个例子描述了任何进程都不能修改另一个已经运行的进程的环境变量。

将变量

Counter
作为持久存储的 user 环境变量进行管理的解决方案是:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Counter=0"
for /F "skip=2 tokens=1,3" %%I in ('%SystemRoot%\System32\reg.exe QUERY HKCU\Environment /v Counter 2^>nul') do if /I "%%I" == "Counter" set "Counter=%%J"
set /A Counter+=1
%SystemRoot%\System32\setx.exe Counter %Counter% >nul
endlocal

首先在 local 环境中定义了一个环境变量

Counter
,其值为
0

接下来,执行注册表查询以获取持久存储的 user 环境变量

Counter
的当前值,并将该值分配给 local 环境变量
Counter
(如果存在于当前用户的注册表配置单元中)。

local环境变量

Counter
的值加一。

新值被写回注册表,以使用 SETX 更新持久存储的 user 环境变量 Counter 的值,该值将消息 WM_SETTINGCHANGE 发送到所有顶级应用程序窗口。

也可以使用 SETX 命令行来代替:

%SystemRoot%\System32\reg.exe ADD HKCU\Environment /f /v Counter /d %Counter% >nul

该命令行还更新持久存储的 user 环境变量

Counter
的值,但不发送 Windows 消息
WM_SETTINGCHANGE
,并且也可以在没有
%SystemRoot%\System32\setx.exe
的 Windows XP 上工作。

删除持久的 user 环境变量

Counter
需要执行命令行:

%SystemRoot%\System32\reg.exe DELETE HKCU\Environment /f /v Counter >nul

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • echo /?
  • endlocal /?
  • for /?
  • reg /?
  • reg add /?
  • reg delete /?
  • reg query /?
  • set /?
  • setlocal /?
  • setx /?

阅读有关 使用命令重定向运算符的 Microsoft 文档,了解

2>nul
的说明。重定向运算符
>
必须在
FOR
命令行上使用脱字符号 ^ 进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的
reg
命令行)之前处理此命令行时将其解释为文字字符使用在后台启动的单独命令进程,并使用
%ComSpec% /c
'
中的命令行作为附加参数。

注意: 如果两个正在运行的批处理文件同时执行四到六个或多或少的三个命令行,则持久存储的 user 环境变量

Counter
的值只会增加 1,而不是 2,因为两个批处理文件同时从注册表读取相同的值,在本地递增该值,并用相同的值更新注册表中的值。需要更多代码来处理这样的并行
Counter
值更新用例。


0
投票

这不是答案,只是一些想法。

  1. 您可以使用新的 cmd 窗口名称作为计数器,无需
    SETX
    REG.EXE

杀死相同的进程:

taskkill /f /fi "windowtitle eq counter*" /fi "imagename eq cmd.exe"

然后开始新的流程:

start cmd /k title counter 100
(例如计数器值等于100)

要搜索具有当前计数器值的窗口名称,请使用命令:

for /f "delims=, tokens=9" %%i in ('tasklist /fi "windowtitle eq counter*" /fo csv /nh /v') do set "counter= %%~i"

获取价值:

set "counter=%counter:*counter =%"

  1. 如果您打算使用
    SETX
    通过 Powershell 获取计数器值:
    powershell -nop -c [System.Environment]::GetEnvironmentVariable('counter','user')

但这是一种古怪的方式,因为改进的 PS 取代了 Batch Scripting。所以没有理由混合使用这些工具。

附注还有一种使用实际环境变量执行批处理的方法(SO 中描述):

start /i /wait "" "%windir%\explorer.exe" batch-file.cmd

© www.soinside.com 2019 - 2024. All rights reserved.