为什么使用 SetX 还会将其他文件夹路径添加到系统 PATH 而不仅仅是指定的文件夹路径?

2024-01-15

我有一个批处理文件,我使用 C++ 调用该文件system("name.bat")。在该批处理文件中,我尝试读取注册表项的值。从 C++ 调用批处理文件会导致set KEY_NAME=HKEY_LOCAL_MACHINE\stuff失败。

但是,当我直接运行批处理文件(双击它)时,它运行良好。不确定我做错了什么。

批处理文件:

set KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Ansoft\Designer\2014.0\Desktop
set VALUE_NAME=InstallationDirectory
REG QUERY %KEY_NAME% /v %VALUE_NAME%

C++ 文件:

int main(void)
{
    system("CALL C:\\HFSS\\setup_vars.bat");
    return 0;
}

更新1:

我发现密钥实际上位于 64 位注册表中,而我正在将 C++ 解决方案构建为 32 位。一旦我解决了这个问题,它发现注册表项很好。

现在我在将该路径添加到我的PATH多变的。它不是创建系统变量,而是创建用户变量PATH并将其添加到那里。

从命令行运行有效。

Code:

set KEY_NAME=HKLM\SOFTWARE\Ansoft\Designer\2014.0\Desktop\
set VALUE_NAME=InstallationDirectory

FOR /F "usebackq skip=1 tokens=1,2*" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME%`) DO (
   set ValueName=%%A
   set ValueType=%%B
   set ValueValue=%%C
)

if defined ValueName (
   @echo Value Value = %ValueValue%
) else (
   @echo %KEY_NAME%\%VALUE_NAME% not found.
)

:: Set PATH Variable
set path_str=%PATH%
set addPath=%ValueValue%;

echo %addPath%
echo %ValueValue%

echo %PATH%| find /i "%addPath%">NUL

if NOT ERRORLEVEL 1 (
   SETX PATH "%PATH%
) else (
   SETX PATH "%PATH%;%addPath%;" /M
)

更新2:

我移动了选项 /M 的位置,它现在添加到右侧PATH多变的。

但是,当我这样做时,它添加了PATH不止一次(3次),然后它还添加了 Visual Studio amd64 文件夹的路径。

我不知道为什么会发生这种情况。


Windows内核库函数创建进程 https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw为新进程创建启动新进程的进程的整个环境表的副本。因此,在启动 C++ 应用程序时,您的应用程序会获取环境表,包括PATH来自父进程,Windows资源管理器或者在你的情况下视觉工作室。和这个PATH被复制为cmd.exe在批处理文件开始时。

考虑到从Windows桌面到批处理文件的整个进程树,已经制作了多个副本PATH有些进程可能会在其本地副本中附加一些内容PATH like 视觉工作室已经完成,或者甚至已经删除了路径PATH.

你现在做什么SETX PATH "%PATH%正在附加本地副本PATH进程树中的父进程已将其完全修改为系统PATH而不检查重复的路径。

更好的办法是使用本地副本丢弃所有代码PATH而是读取系统的值PATH,检查你要添加的路径是否已经在系统中PATH如果不是这种情况,请附加您要添加​​到系统的路径PATH using setx.

这应该在不扩展系统中的环境变量的情况下完成PATH like %SystemRoot%\System32 to C:\Windows\System32.


以下是在 Windows XP SP3 x86、Windows 7 SP1 x64 和 Windows 11 22H2 上测试的任务所需的批处理代码。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "KeyName=HKLM\SOFTWARE\Ansoft\Designer\2014.0\Desktop"
set "ValueName=InstallationDirectory"
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query "%KeyName%" /v "%ValueName%" 2^>nul') do (
    if /I "%%G" == "%ValueName%" (
        set "PathToAdd=%%I"
        if defined PathToAdd goto GetSystemPath
    )
)
echo Error: Could not find non-empty value "%ValueName%" under key
echo        %KeyName%
echo(
endlocal
pause
exit /B

:GetSystemPath
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do (
    if /I "%%G" == "Path" (
        set "SystemPath=%%I"
        if defined SystemPath goto CheckPath
    )
)
echo Error: System environment variable PATH not found with a non-empty value.
echo(
endlocal
pause
exit /B

:CheckPath
setlocal EnableDelayedExpansion
rem The folder path to add must contain \ (backslash) as directory
rem separator and not / (slash) and should not end with a backslash.
set "PathToAdd=!PathToAdd:/=\!"
if "!PathToAdd:~-1!" == "\" set "PathToAdd=!PathToAdd:~0,-1!"
if "!SystemPath:~-1!" == ";" (set "Separator=") else set "Separator=;"
set "PathCheck=!SystemPath!%Separator%"
rem Do nothing if the folder path to add without or with a backslash
rem at end with a semicolon appended for entire folder path check is
rem already in the system PATH value. This code does not work with
rem path to add contains an equal sign which is fortunately very rare.
if not "!PathCheck:%PathToAdd%;=!" == "!PathCheck!" goto EndBatch
if not "!PathCheck:%PathToAdd%\;=!" == "!PathCheck!" goto EndBatch
set "PathToSet=!SystemPath!%Separator%!PathToAdd!"
set "UseSetx=1"
if not "!PathToSet:~1024,1!" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
    %SystemRoot%\System32\setx.exe Path "!PathToSet!" /M >nul
) else (
    set "ValueType=REG_EXPAND_SZ"
    if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ"
    %SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /f /v Path /t !ValueType! /d "!PathToSet!" >nul
)
:EndBatch
endlocal
endlocal

上面的批处理代码使用简单的不区分大小写的字符串替换和区分大小写的字符串比较来检查要追加的文件夹路径是否已存在于系统中PATH。仅当众所周知文件夹路径之前是如何添加的并且用户未在 中修改此文件夹路径时,此操作才有效PATH同时。为了更安全地检查是否PATH包含一个文件夹路径请参阅答案如何检查%PATH% 中是否存在目录? https://stackoverflow.com/a/8046515/1012053写于戴夫·本纳姆 https://stackoverflow.com/users/1012053/dbenham.

Note 1:命令setx默认情况下在 Windows XP 上不可用。

Note 2:命令setx将长度超过 1024 个字符的值截断为 1024 个字符。

因此,批处理文件使用命令reg取代系统路径在 Windows 注册表中,如果setx不可用或新路径值太长setx。使用上的缺点reg就是它WM_SETTINGCHANGE https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange消息不会发送到所有顶级窗口,通知作为 Windows 桌面运行的 Windows 资源管理器和其他应用程序有关系统环境变量的此更改。因此,用户必须重新启动 Windows,最好在更改持久存储的 Windows 系统环境变量上的某些内容时执行此操作。

批处理脚本经过测试PATH当前包含带有感叹号的文件夹路径,并且文件夹路径用双引号括起来,仅当文件夹路径包含分号时才需要。

要了解所使用的命令及其工作原理,请打开命令提示符 https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/窗口中,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • reg /?
  • reg add /?
  • reg query /?
  • set /?
  • setlocal /?
  • setx /?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么使用 SetX 还会将其他文件夹路径添加到系统 PATH 而不仅仅是指定的文件夹路径? 的相关文章

  • Windows批处理文件:在for循环中设置变量

    我有许多具有相同命名方案的文件 作为示例 四个文件分别称为 num 001 001 txt num 002 001 txt num 002 002 txt num 002 003 txt 第一组数字代表它来自哪个 包 第二组数字只是用来区分
  • 批处理文件中的 Powershell - 如何转义元字符?

    运行 Windows 7 当我复制文件在例程期间到外部磁盘文件备份 我使用 Powershell v2 从批处理文件 在副本文件上重新创建原始文件的所有时间戳 以下代码在大多数情况下都能成功运行 但并非总是如此 SET file 1 SET
  • shell进程的并行执行

    有没有一个工具可以在 Windows 批处理文件中并行执行多个进程 我发现了一些有趣的 Linux 工具 parallel http mi eng cam ac uk er258 code parallel html and PPSS ht
  • 用于从多个目录复制和重命名文件的批处理文件

    我之前曾寻找过我的问题的答案 但到目前为止还没有具体的答案 看 使用xcopy将多个目录中的文件复制到一个目录 https stackoverflow com questions 585091 using xcopy to copy fil
  • 读取txt文件中的每一行并使用windows dos命令分配变量

    我通过使用 Beyond Compare 命令行比较这 2 个文件夹 将文件从一个路径复制到 svn 工作副本 使用 Beyond Compare 进行比较后将生成报告 如果右侧存在任何额外文件 则应从 svn 存储库中删除 所以我使用下面
  • 将注册表中的版本号转换为System.Version?

    我正在从注册表中检索版本号 如下所示 rKey GetValue Version 现在我想将其转换为System Version object 我该怎么做呢 假设这是一个字符串 string versionText string rKey
  • 在批处理脚本中发送 Windows 密钥

    我最近一直在使用SendKeys使用批处理脚本的函数 我已经了解如何在窗口中输入某些键 例如 Tab 键 SendKeys TAB 或者退格键 SendKeys BACKSPACE 但我一直尝试在不按Windows键的情况下输入它 不幸的是
  • 批处理:在特定程序中打开特定文件?

    当记事本是 txt 文件的默认程序时 如何告诉 Windows 在写字板中打开 C test test txt 接受的答案对我不起作用 我不确定这是因为我试图运行的程序 还是因为路径中有空格 即使我用引号引起来 或者其他原因 不管怎样 我可
  • 午夜后时间设置不正确

    我使用以下命令以更易读的格式获取当前日期 时间 set day date 4 2 set mth date 7 2 set yr date 10 4 set hur time 0 2 set min time 3 2 set bdate d
  • 如何在后台运行python程序以保持活动窗口相同

    我编写了一个程序 可以将前景窗口更改为显示器尺寸的 85 并且要成功运行 前景窗口需要保持不变 我已将 python 脚本 pyw 放入批处理文件 运行 pythonw 并在桌面上创建了批处理文件的快捷方式 并提供了快速运行它的快捷方式 我
  • 批量设置命令的输出和错误以分隔变量

    在Windows 7批处理 cmd exe命令行 中 我试图将命令的标准输出 stdout 和标准错误 stderr 重定向到单独的变量 因此第一个变量设置为输出 第二个变量设置为输出 变量设置为错误 如果有 而不使用任何临时文件 我已经尝
  • 被拒绝:将映像推送到 gitlab 注册表时,请求的资源访问被拒绝

    我正在尝试将图像推送到 gitlab 注册表 我已经做过很多次了 所以我想知道为什么会出现这个错误 我使用最新标签构建图像 Successfully tagged registry gitlab com mycompany rgpd api
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • 当用户在 ActiveSync 中选择“文件 - 同步设置”时,如何确定更新哪个注册表设置?

    我不再确定 GuestOnly 是否确实是我需要更改的注册表项 以防止手持设备与其所连接的 PC 之间的文件同步 如果我打开 ActiveStync 的 Windows Mobile 设备中心 选择 移动设备设置 然后选择 更改内容同步设置
  • 批处理文件删除目录中除指定列表之外的所有文件夹

    我正在寻找一个批处理文件 该文件将进入 C Documents and Settings 并删除除我想保留的几个文件夹之外的所有文件夹 这是一个破解方法 D 如果您在folders txt 中有一个文件夹路径列表 如下所示 C Docume
  • 如何获取字符串的最后一个单词?

    我有一个批处理文件 它以文件路径作为参数 set filePath 1 现在 假设文件路径是 C Temp Folder 我想设置Folder在一个新变量中 我怎样才能做到这一点 我在网上搜索了一下 所有的解决方案都是这样的 for A i
  • 批处理脚本生成特定年月、周和工作日的文件夹

    最近几天我一直在寻找这个问题的答案 有很多关于全年批量文件夹创建的答案 但不够具体 所以我非常感谢答案 所以我想要这样的文件夹结构 如下所示 2017 for example main folder for year 2017 01 JAN
  • 我可以从命令行或 MS-Dos 启用/禁用网络连接吗?

    我想从 Windows 8 中的命令行启用 禁用网络连接 netsh interface set interface Local Area Connection DISABLED 要启用该接口 您需要运行 netsh interface s
  • 使用参数将变量从 vbscript 传递到批处理文件

    请问如何将 inp 变量从这段 vb 传递到我的名为 job bat 的批处理 确实 在从 job bat 进行回显 echo 2 时 我注意到 inp 未正确传递 提示命令视图 inp而不是从 vbs 检索到的值 谢谢 For Each
  • 如何使用批处理文件复制(和增量)文件的多个实例

    我需要创建一个批处理文件来复制文件并在将其放置到目的地时递增它 例子 copy C TEMP MyDoc txt E MyData 本质上 我需要这个复制命令在每次启动时进行复制 现在效果很好 我希望它增加文件名而不是覆盖它 如果我运行此命

随机推荐

  • 从 fasta 文件中删除多个序列

    我有一个字符序列的文本文件 由两行组成 标题和下一行中的序列本身 该文件的结构如下 gt header1 aaaaaaaaa gt header2 bbbbbbbbbbb gt header3 aaabbbaaaa gt headerN a
  • 将 docker 映像从 GCR 拉入 GKE 时出错“无法拉取映像 .... 403 Forbidden”

    背景 我有一个 GKE 集群突然无法从 GCR 提取我的 docker 镜像 两者都在同一个 GCP 项目中 它已经运行良好几个月了 提取图像没有任何问题 现在在没有进行任何更改的情况下开始抛出错误 注意 我通常是团队中唯一访问 Googl
  • 记录亚马逊 Alexa 未处理的话语

    是否可以记录用户提出的触发未处理意图的问题 我打算做什么 当用户说出 Alexa 无法理解的话语时 它会触发未处理的意图 这里我想请用户重复该语句并将其存储在数据库中以供将来参考 这需要我创建一个意图 期望有一个可以接受语句的槽 即槽值不会
  • 应用程序版本未显示在 Spring Boot Banner.txt 中

    运行应用程序时 banner txt 中定义的应用程序版本不会显示在控制台上 它的定义是根据Spring Boot 文档 http docs spring io spring boot docs current SNAPSHOT refer
  • Python:在PDF中搜索文本

    我想写一个这样的函数 输入 一个 PDF 文件 一个字符串 该 PDF 是可搜索的 例如 它是由 MS Word 创建的 输出 PDF 文件中字符串的页面和位置 坐标 x 和 y 如果有 你能给我一些提示 什么库 方法 来用Python来做
  • C++ 标准库或其他广泛使用的库中的单链表?

    好像C 标准库里只有双向链表 没有单链表 吧 是否有广泛使用的带有单链表的 C 库 有的是slist http www boost org doc libs 1 35 0 doc html intrusive slist htmlBoost
  • 将 git 子模块与 python 一起使用

    我在这个网站上阅读了很多关于 git 子模块使用的博客文章和问题 但仍然不知道如何更好地在 python 中使用它们 我的意思是 如果我有这样的包 管理依赖项的更简单方法是什么 mypkg init py setup py submodul
  • 在 Spark RDD 和/或 Spark DataFrame 中重塑/旋转数据

    我有一些以下格式的数据 RDD 或 Spark DataFrame from pyspark sql import SQLContext sqlContext SQLContext sc rdd sc parallelize X01 41
  • 为什么scanf可以将errno设置为零?(当输入“ctrl+D”时)

    手册告诉我们 errno永远不会被任何系统调用或库函数设置为零 但我想知道 为什么以下代码中的errno可以通过scanf设置为零 当scanf 输入 ctrl D 时 include
  • 没有让 JSR303 注释与 Tomcat 7 一起使用

    经过几个小时的谷歌和几个教程后 我被击败了 事实并不是我收到的错误可以给我提示问题是什么 而是完全没有错误让我发疯 下面的代码可以工作 只是没有达到应有的效果 用于检查输入不为空或长度小于 3 个字符的注释永远不会运行 当部署项目或写入 n
  • 如何确定 Java 应用程序的主类?

    我们正在开发一个平台 许多开发人员将在其中编写自己的 ETL 应用程序 这些应用程序使用供应商的 API 然后将其提交到平台上执行 我们希望限制开发人员在编写 Main 类 通常只使用供应商的 API 时不要只顾自己的事情 以促进一些牢固的
  • 版本号 float、decimal 或 double

    我有一个文档管理系统 其中文档可以有多个版本 每个版本都会被保存 用户可以查看版本历史记录 我想知道的是 我应该使用什么数据类型作为版本号 小数 浮点还是双精度 我正在使用 NET 和 C 版本号开始于0 1以及每一个发表的major版本将
  • 分段函数 lmfit

    我正在尝试定义一个分段函数 以便由 Python 中的 lmfit 库拟合 我遇到的问题是我为该函数定义的参数不会与我提交的数据一起评估 我有一个与我的案例有点相似的例子here https stackoverflow com questi
  • 如何在 bash 中使用正则表达式验证版本号是否有效?

    我正在尝试验证版本号是否与版本模式匹配 但似乎检查由于某些奇怪的原因而失败 bin bash VERSION 1 2 3 if VERSION d d d then echo INFO lt gt Version VERSION else
  • Rails 将参数传递给 ActiveRecord 回调函数

    我的一个 AR 模型中有以下代码片段 after update cache bust The cache bust模型中的方法接受一个参数 布尔值 该参数将自身的值设置为false默认情况下 我怎样才能通过true从我上面定义的 Activ
  • 带参数的 Flask 表单

    我正在尝试用一个参数定义 Flask 表单 这是我的方法 forms py class RegisterPatternForm FlaskForm cursorPatients MongoClient localhost 27017 myD
  • 使用 Dask 的新 to_sql 来提高效率(内存/速度)或替代方案将数据从 dask 数据帧获取到 SQL Server 表

    我的最终目标是结合使用 SQL Python 来处理一个项目 该项目的数据量太大 以至于 pandas 无法处理 至少在我的机器上 所以 我已经和dask to 从多个源读取数据 主要是 SQL Server 表 视图 将数据操作 合并到一
  • itext XMLWorkerHelper 忽略
  • 标记的 value 属性
  • 我使用 itext 5 4 5 和 XMLWorker 5 4 5 从来自 ckEditor 的 html 生成 pdf 用户还可以从 Word 文档粘贴一些文本 有时会产生如下结果 ol li value some text1 li ol
  • 哪些 C# 方法名称不应被混淆?

    我正在开发一个 C 混淆程序 我想知道是否有一些方法名称 硬连线 到框架中 因此不应修改 我首先想到的是 ctor cctor 和 Dispose 还有其他我应该避免修改的吗 编辑 为了详细说明 并受到 Paul Alexander 的启发
  • 为什么使用 SetX 还会将其他文件夹路径添加到系统 PATH 而不仅仅是指定的文件夹路径?

    我有一个批处理文件 我使用 C 调用该文件system name bat 在该批处理文件中 我尝试读取注册表项的值 从 C 调用批处理文件会导致set KEY NAME HKEY LOCAL MACHINE stuff失败 但是 当我直接运