我正在编写一个Windows应用程序。作为此应用程序的一部分,我想在安装时修改用户的PATH变量。我希望使用任何.bat命令来完成此操作,但我对任何不涉及第三方软件或不强制用户重新启动计算机的可能性感兴趣。如果有任何帮助,我将使用NSIS进行安装。
我知道setx
。然而,使用它似乎有一个1024 character limit,虽然这是可以克服的,我更担心在PATH中丢失对环境变量的引用。请参阅Harry约翰斯顿在this thread中对这个问题的评论。我能找到的所有资源都是旧的,还有一些人们宣传的软件包,例如pathed
。但是,在不使用第三方软件的情况下,是否真的没有安全的方法来更新windows上的PATH变量?
在我链接的第一个线程上也有一个涉及使用PowerShell的路线,但是这不会有Harry约翰斯顿在他的评论中提到的同样的限制吗?该路由也被称为here,该线程上的答案要绕过setx的1024个字符限制,需要用户重新启动计算机,我宁愿避免这种情况。解决方法包括设置一个变量本身来触发广播消息,但是对于我们重置的随机变量来说,1024个字符的限制不还是一个问题吗?更不用说这感觉相当不好。
改变路径似乎是一件应该是常见的事情,这样做的最佳实践是什么?
1条答案
按热度按时间gblwokeq1#
我写了几个批处理文件的过程来添加或删除一个文件夹路径到user或system环境变量
PATH
,见these answers,但我还没有找到一个解决方案,真正工作的每一个可能的文件夹路径添加或PATH
变量的每一个可能的现有值使用一个批处理文件,只有Windows commands。需要处理的一些问题包括:
1.要添加的文件夹路径包含分号,需要添加用
"
括起来的文件夹路径,以获得有效的分号分隔的文件夹路径列表。1.要添加的文件夹路径包含一个等号,这使得在使用批处理文件时,检查该文件夹路径是否已存在于环境变量
PATH
的值中变得非常困难,甚至可能是不可能的。1.现有的
PATH
值已经包含一个"
中的文件夹路径,原因可能是文件夹路径包含;
或其他安装程序,或者用户操作不当,不必要地添加了一个带有双引号的文件夹路径。1.已经存在的
PATH
值已经包含一个带有等号的文件夹路径,这使得检查要添加的文件夹路径是否已经存在于环境变量PATH
的值中变得非常困难,甚至可能是不可能的。1.Windows Command Processor
cmd.exe
处理批处理文件时,默认情况下使用每个字符一个字节的编码,并根据国家/地区使用OEM代码页。这是一个问题,尤其是在亚洲国家,用户经常使用他们的真实的姓名作为用户帐户名,因此环境变量USERNAME
和USERPROFILE
包含Unicode编码在 *Windows命令处理器 * 使用的代码页中根本没有可用的字符。在这种使用情况下,使用批处理文件更新user或system环境变量PATH
可能会损坏现有的PATH
值。Windows应用程序或脚本的开发人员应始终考虑避免向user或system环境变量
PATH
添加文件夹路径的设计。始终可以在编写应用程序和脚本时不向user或system添加文件夹路径环境变量PATH
。由安装程序存储以供已安装的应用程序或脚本使用的文件夹路径也可以存储在Windows注册表中注册表项Software\CompanyName\ProgramName
下的其他位置在HKEY_CURRENT_USER
中(当前用户)或HKEY_LOCAL_MACHINE
(所有用户)以及存储在%APPDATA%\CompanyName\ProgramName
目录下的配置文件中(当前用户)或%ALLUSERSPROFILE%\CompanyName\ProgramName
(所有用户)。如果程序/脚本依赖于添加到user或system的文件夹路径,则通常表示应用程序/脚本设计不正确环境变量PATH
以确保正常工作。仅当用户很可能主要从控制台中使用应用程序/脚本时,才应在安装过程中向user或system环境变量
PATH
添加文件夹路径(Windows命令提示符、PowerShell控制台、Windows终端),方法是键入不带文件扩展名的文件名以及各种参数,并且仅在安装期间询问用户是否应将应用程序/脚本文件夹路径添加到user或system环境变量PATH
以便于使用应用程序/脚本文件夹路径之后脚本。用户可能不经常使用应用程序/脚本,因此不希望将应用程序/脚本的文件夹路径从控制台添加到用户或系统环境变量PATH
,它影响许多其他应用程序和脚本的执行时间,并使文件系统访问次数增加近每一个过程。使用由
cmd.exe
仅使用 *Windows命令处理器 * 的内部命令和其他Windows命令处理的批处理文件的主要问题是,cmd.exe
是为执行命令和可执行文件而设计的,而不是为字符串处理而设计的,而字符串处理由更现代、功能更强大的脚本解释器(如 Windows Script Host 或 PowerShell)提供本机支持。这使得处理诸如PATH
的持久性存储环境变量的现有值,以便使用用户定义的文件夹路径或用户的帐户配置来更新它成为一个噩梦。现有的PATH
值以及要添加的文件夹路径可能包含对 * 命令处理器 * 具有特殊意义的字符。这使得纯批处理文件解决方案很难真正用于任何可能的用例,甚至是不可能的。这里是一个注解的批处理脚本,适用于将文件夹路径添加到user环境变量
PATH
的常见用例。它甚至可以在Windows XP上工作,其中SETX根本不可用,并且仅在结果值不超过1024个字符限制时使用SETX。否则使用命令REG来更新注册表值,其缺点是Windows shell不会收到有关user环境变量PATH
更改的消息。对于更新的user,用户必须至少登录/注销并重新登录/登录环境变量PATH
对用户帐户下运行的所有进程生效。字符串
**注意:**环境变量
PathToAdd
必须在此批处理文件的第三行根据需要定义。更新user环境变量
PATH
的前四个问题由此脚本处理,不更新持久存储的环境变量,而是通知用户原因以及用户现在应该做什么来将文件夹路径添加到user环境变量PATH
。第五个问题是缺少对要添加的路径或user环境变量
PATH
的现有值中包含Unicode字符的文件夹路径的支持,此批处理文件根本无法处理。检查要添加的文件夹路径是否已经存在于user
PATH
的值中,这是非常糟糕的,因为这是通过简单的不区分大小写的字符串比较完成的。可能是要添加的文件夹路径使用像%APPDATA%\Python
这样的变量引用作为值,而相同的文件夹路径已经存在于user中PATH
值以扩展的形式出现,如C:\Users\UserName\AppData\Roaming\Python
。这在用户使用错误编码的安装程序时非常常见,该安装程序使用所有环境变量的扩展来更新持久存储的环境变量PATH
,而不是保留环境变量引用。上面的批处理代码会将文件夹路径添加到持久存储的user环境变量PATH
由于%APPDATA%\Python
而不存在于包含C:\Users\UserName\AppData\Roaming\Python
的现有值中。如果安装是由用户从命令提示符窗口启动的,即一个已经在运行的
cmd.exe
进程,则在安装过程中更新user环境变量PATH
的批处理文件在退出批处理文件处理之前,还应该在任何本地环境设置之外通过命令SETSTANDARD更新local环境变量PATH
。另外,最好检查用户使用的控制台是否是真实的,从批处理文件中的PowerShell控制台是通过
%ComSpec% /c ""Fully qualified batch file name""
的隐式执行的。在这种情况下,应通知用户必须关闭PowerShell控制台窗口,并从Windows shell打开一个新窗口(Windows桌面,Windows开始菜单,如果由于命令REG而不需要登录/注销和登录/登录或完全重新启动Windows,用于更新持久存储的环境变量,而不是SETX。依赖于本地中特定文件夹路径的应用程序/脚本
PATH
应始终通知用户在安装后重新启动Windows,在卸载后分别将文件夹路径添加到永久存储的PATH
中,并从永久存储的PATH
中删除文件夹路径,然后再执行其他操作,以确保修改后的PATH
真正有效for the processes流程.用户不喜欢在安装或卸载应用程序/脚本后重新启动Windows,并且经常忽略该建议或请求。但是这些用户接下来经常抱怨刚刚安装的应用程序无法正常工作,并向其他人寻求帮助,例如在Stack Overflow上。这样的应用程序/脚本的开发人员可以避免在使用应用程序/脚本的设计时遇到的许多麻烦。不依赖于安装过程中添加到
PATH
的文件夹路径的脚本。要了解所使用的命令及其工作方式,请打开command prompt窗口,在那里执行以下命令,并仔细阅读显示的每个命令的帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg /?
reg add /?
reg query /?
rem /?
set /?
setlocal /?
setx /?
有关
2>nul
的解释,请阅读有关Using command redirection operators的Microsoft文档。在执行命令FOR之前,Windows命令解释器处理第一个FOR命令行时,必须使用插入字符^
对重定向运算符>
进行转义,以将其解释为文字字符它使用在后台启动的单独命令进程执行嵌入式reg
命令行,并将'
中的命令行作为附加参数附加。另请参阅:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?的
What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?这个较长的答案描述了Windows对
PATH
的管理以及CMD对它的使用。Length limitations of PATH,其中包含有关
PATH
值变得太长时发生的情况的信息。How to pass environment variables as parameters by reference to another batch file?这个答案详细描述了每次执行SETSTACK和ENDSTACK命令时在后台发生的事情,这对于理解上面的代码很重要。
Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files,详细介绍了如何通过CMD的内部命令IF进行字符串比较,以及为什么在批处理文件中处理包含一个或多个
"
的字符串如此困难。Why is no string output with 'echo %var%' after using 'set var = text' on command line?
this answer中的常规问题章节解释了为什么上面的代码在这里发布。
关于Application Registration的Microsoft文档页面解释了在安装过程中如何注册Windows应用程序,不幸的是,许多应用程序安装程序都没有这样做。