【问题标题】:How to set a variable for the current OS session only如何仅为当前操作系统会话设置变量
【发布时间】:2014-08-11 13:12:08
【问题描述】:

setx 永久修改环境变量。
set 仅在批处理脚本期间使变量可用。
有什么方法可以设置变量以保持其值直到系统重新启动?
例如。在我的批处理文件中,我正在检查变量是否设置如下:

if %MYVAR% == 1 (
<block>
)

【问题讨论】:

    标签: windows variables batch-file command-line windows-7


    【解决方案1】:
    @ECHO Off
    IF NOT EXIST q25244121.org GOTO done
    :: reset to original
    FOR /f "tokens=1*delims==" %%a IN (q25244121.org) DO (
     IF DEFINED %%a FOR /f "tokens=1*delims==" %%p IN ('set %%a') DO (
      IF "%%a"=="%%p" IF "%%b" neq "%%q" SET "%%a=%%b"
     )
    )
    :: Delete if not originally defined
    FOR /f "tokens=1*delims==" %%p IN ('set') DO (
     FINDSTR /L /i /c:"%%p=" q25244121.org >NUL
     IF ERRORLEVEL 1 SET "%%p="
    )
    
    :done
    :: Record current settings
    set>q25244121.org
    
    EXIT /b
    

    这可能对你有用。您需要将 CAPS 中的 SET 指令更改为 SETX。毫无疑问,临时文件也需要放在用户名是您要使用的名称的一部分的文件中。

    如果您要将此批处理包含在您的启动目录中,那么它应该恢复上次保存的环境变量的值。

    因此,在第一次登录时,当前变量的值会被存储。在后续登录时,环境将恢复到上次存储的环境,无论是否执行了 setx

    但是,您需要更改程序。这将恢复到已知状态。如果你真的想setx 一个值或安装一些软件来添加新的环境变量值或更改现有的值(PATH 将在这里最喜欢)那么你需要首先运行这个例程,进行更改,删除保存文件并重新运行此例程。尴尬,我承认 - 但这是一种方法。

    哦-记住set你的变量在拥有setx它之后。您甚至可以将setxX 批处理写入setx,然后将set(反之亦然)写入所需的变量。

    【讨论】:

    • 对不起。恐怕我不明白这种方法如何区分 当前操作系统会话的 cmd.exe 会话和后操作系统会话的会话(在用户注销或系统重新启动之后)。我知道这种方法可能会将 第一个 cmd.exe 会话与后面的会话区分开来,但这不是 OP 要求的重点。
    • @Aacini :可能你错过了关键点,大写的SET 命令应该变成SETX。当这个例程第一次运行时,文件记录了当时的设置。随后的任何cmd 会话中的任何SETX 都将更改未来cmd 设置的值 - 直到下一次登录,此时该例程再次运行。它检测任何SETX 在上一个操作系统会话中应用的差异,并将SETXs 它们返回到文件中的条件,正如最初记录的那样,新操作系统会话中的cmd 会话(一旦这个启动批处理完成)很干净。
    • 实际上,如果这个例程是CALLed,而不是将SETs 更改为SETXs,那么它将在特定的CMD 会话中恢复原始环境,这也可能有用。
    • 好的。我得到了它。您解决方案中的关键点是批处理文件必须复制到每个用户的启动目录。我认为您的回答中没有明确说明这一点...
    【解决方案2】:

    您可以通过使用 JScript 的 WshShell.Environment 方法的 Batch-JScript 混合脚本来执行此操作。 documentation 指定有四种类型的环境:System、User、Volatile 和 Process,而 Volatile 类型“适用于当前登录会话并且在注销和重新启动之间不保存”,这正是您想要的:

    @if (@CodeSection == @Batch) @then
    
    @echo off
    
    rem Define a persistent variable for the current OS session only via JScript
    Cscript //nologo //E:JScript "%~F0" MYVAR "This is the value"
    goto :EOF
    
    @end
    
    var colEnvVars = WScript.CreateObject("WScript.Shell").Environment("Volatile");
    colEnvVars(WScript.Arguments(0)) = WScript.Arguments(1);
    

    您必须将以前的代码保存在 .bat 文件中,并将其作为任何批处理文件执行。请注意,以这种方式定义的变量当前 cmd.exe 窗口中可用,但仅在同一操作系统会话中打开的未来 cmd.exe 窗口中可用。

    在 Windows 8.1 上测试。

    【讨论】:

      【解决方案3】:

      好吧,我发现了一种比 JScript 方法更简单(而且显然不那么 hacky)的方法,但它通过易变的环境操作使我们朝着正确的方向前进。

      只需使用reg 命令来操作注册表中的 volatile 环境:

      reg add "HKCU\Volatile Environment" /v "%MYVAR%" /d "%MYVALUE%" /f
      

      reg add 都可以创建和更新值。

      \f 绕过覆盖确认。

      \d ""设置一个空数据相当于删除了全局变量。您不会在带有 set 的 shell 中看到它,但您仍然可以在注册表中看到它是空的。

      这是一个参考:https://ss64.com/nt/reg.html

      【讨论】:

        猜你喜欢
        • 2010-11-06
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 2011-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多