系统环境变量全部丢失
lsrweb opened this issue · comments
是的 我刚刚也遇到了 那应该还是 nsis 的脚本有点问题 之前还特意反复测试过很多次 十分抱歉 我这边赶紧修复一下这个问题 也应该会造成困扰 抱歉
我先把这个alpha版本下架一下 修复了再重新发布
之前备份的注册表太老了,有没有办法可以还原系统path呢
只需要恢复大部分的系统级的就行
只需要恢复大部分的系统级的就行
我找到了之前的window系统还原点,我去试试还原一下
再次抱歉啊 nsis的脚本语言的我现在还不是特别熟悉 所以应该还是有一些问题 nsis脚本文件在这里:https://github.com/1111mp/nvm-desktop/blob/tauri/src-tauri/templates/nsis-hooks.nsh
我现在在排查到底是什么问题造成的 抱歉啊
!include "StrFunc.nsh"
${StrStr}
${UnStrStr}
${UnStrRep}
!macro NSIS_HOOK_POSTINSTALL
; Get the current user's %HOMEDRIVE% and %HOMEPATH%
ReadEnvStr $0 "HOMEDRIVE"
ReadEnvStr $1 "HOMEPATH"
StrCpy $1 "$0$1\.nvmd\bin"
; Read the system-wide PATH environment variable
ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
StrCmp $2 "" 0 +2
StrCpy $2 "$2;"
; Check if the directory is in your PATH
${StrStr} $3 "$2" "$1"
StrCmp $3 "" 0 +3
; If the directory is not in PATH, add it
StrCpy $2 "$2$1"
; Update the registry
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$2"
; Notify the system that environment variables have been updated
System::Call 'KERNEL32::SendMessageTimeoutA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)'
!macroend
!macro NSIS_HOOK_PREUNINSTALL
; Get the current user's %HOMEDRIVE% and %HOMEPATH%
ReadEnvStr $0 "HOMEDRIVE"
ReadEnvStr $1 "HOMEPATH"
StrCpy $1 "$0$1\.nvmd\bin"
; Read the system-wide PATH environment variable
ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
; Ensure $2 is not empty
StrCmp $2 "" done
; Check if the directory is in your PATH
${UnStrStr} $3 "$2" "$1"
StrCmp $3 "" done
; If the directory is in PATH, remove it
; Remove the middle path
${UnStrRep} $4 "$2" "$1;" ""
${UnStrRep} $4 "$4" ";$1" "" ; Remove the path at the beginning
${UnStrRep} $4 "$4" "$1" "" ; Remove the trailing path
; Remove extra semicolons
${UnStrRep} $4 "$4" ";;" ";"
; Fix possible leading and trailing semicolons
${UnStrRep} $4 "$4" "^;" "" ; Remove the leading semicolon
${UnStrRep} $4 "$4" ";$" "" ; Remove the trailing semicolon
; Update the registry
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$4"
; Notify the system that environment variables have been updated
System::Call 'KERNEL32::SendMessageTimeoutA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)'
done:
!macroend
确保追加路径:在NSIS_HOOK_POSTINSTALL宏中,确保在现有的PATH变量末尾追加新路径,而不是覆盖。安全移除路径:在NSIS_HOOK_PREUNINSTALL宏中,确保在移除路径时保留其他路径不变,并处理多余的分号。避免覆盖现有变量:始终保留并修改现有的PATH变量内容,避免导致系统级路径丢失。
再次抱歉啊 nsis的脚本语言的我现在还不是特别熟悉 所以应该还是有一些问题 nsis脚本文件在这里:https://github.com/1111mp/nvm-desktop/blob/tauri/src-tauri/templates/nsis-hooks.nsh
我现在在排查到底是什么问题造成的 抱歉啊
问题不大,相信Windows的还原,公司没啥事,我又摸了一上午的鱼
Windows的还原,公司没啥事,我又摸了一上午的
系统还原点生效了,环境变量没问题
!include "StrFunc.nsh" ${StrStr} ${UnStrStr} ${UnStrRep} !macro NSIS_HOOK_POSTINSTALL ; Get the current user's %HOMEDRIVE% and %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; Read the system-wide PATH environment variable ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCmp $2 "" 0 +2 StrCpy $2 "$2;" ; Check if the directory is in your PATH ${StrStr} $3 "$2" "$1" StrCmp $3 "" 0 +3 ; If the directory is not in PATH, add it StrCpy $2 "$2$1" ; Update the registry WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$2" ; Notify the system that environment variables have been updated System::Call 'KERNEL32::SendMessageTimeoutA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' !macroend !macro NSIS_HOOK_PREUNINSTALL ; Get the current user's %HOMEDRIVE% and %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; Read the system-wide PATH environment variable ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" ; Ensure $2 is not empty StrCmp $2 "" done ; Check if the directory is in your PATH ${UnStrStr} $3 "$2" "$1" StrCmp $3 "" done ; If the directory is in PATH, remove it ; Remove the middle path ${UnStrRep} $4 "$2" "$1;" "" ${UnStrRep} $4 "$4" ";$1" "" ; Remove the path at the beginning ${UnStrRep} $4 "$4" "$1" "" ; Remove the trailing path ; Remove extra semicolons ${UnStrRep} $4 "$4" ";;" ";" ; Fix possible leading and trailing semicolons ${UnStrRep} $4 "$4" "^;" "" ; Remove the leading semicolon ${UnStrRep} $4 "$4" ";$" "" ; Remove the trailing semicolon ; Update the registry WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$4" ; Notify the system that environment variables have been updated System::Call 'KERNEL32::SendMessageTimeoutA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' done: !macroend确保追加路径:在NSIS_HOOK_POSTINSTALL宏中,确保在现有的PATH变量末尾追加新路径,而不是覆盖。安全移除路径:在NSIS_HOOK_PREUNINSTALL宏中,确保在移除路径时保留其他路径不变,并处理多余的分号。避免覆盖现有变量:始终保留并修改现有的PATH变量内容,避免导致系统级路径丢失。
目前这个脚本有问题吗 或者你有时间可以提交一个pr 我本地改了一下 我先提交一个commit 你可以检查一下 这是最新的提交 56f1e0ff8f4f02decd4b9b04b2174301000a72aa
我问了一下chatgpt 它说改了之后可以确保保留系统之前的PATH 额... 我本地打包反复安装了几次 好像不会出现这个问题了 不过还是怕
我问了一下chatgpt 它说改了之后可以确保保留系统之前的PATH 额... 我本地打包反复安装了几次 好像不会出现这个问题了 不过还是怕
来个包包,我来测一手
发布好了 我下载到本地安装没复现了 你可以试试
还是会吗 你能把你之前的path 复制给我一份吗 点击编辑文本 然后复制粘贴出来就好 我本地测试一下
还是会吗 你能把你之前的path 复制给我一份吗 点击编辑文本 然后复制粘贴出来就好 我本地测试一下
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.5\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.5\libnvvp;D:\nodejs\node_global;C:\Program Files (x86)\Yarn\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C:\Users\29017.nvmd\bin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Users\29017\AppData\Local\Microsoft\WindowsApps;C:\Users\29017\AppData\Local\JetBrains\Toolbox\scripts;D:\DevTools___\Microsoft VS Code\bin;D:\Dev;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0;%SYSTEMROOT%\System32\OpenSSH;C:\Program Files\dotnet;D:\Windows Kits\10\Windows Performance Toolkit;C:\Program Files\GitHub CLI;D:\DevTools___\Git\cmd;D:\DevTools___\微信web开发者工具\dll;C:\Program Files\NVIDIA Corporation\Nsight Compute 2024.2.1;C:\Users\29017\miniconda3\envs\311;C:\Program Files\NVIDIA Corporation\NVIDIA app\NvDLISR;C:\Program Files\PowerShell\7;D:\DevTools___\Git\bin;%JAVA_HOME%\bin;
你也记得备份一下环境变量,我恰午饭去咯
这是我在系统还原点还原后备份出来的环境变量,你试试吧
问题应该已经定位到了 就是路径如果存在中文的时候 那么获取系统环境变量获取到的就是空字符串 ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
这个问题我看应该咋解决
原来是微信开发工具的锅😡
也有其它问题 比如路径太长 超出了nsis的支持的最大长度的话 也会出现这个问题
也有其它问题 比如路径太长 超出了nsis的支持的最大长度的话 也会出现这个问题
这个nsis就是逊啊,长一点就不行了
应该是变量的长度 脚本中读取整个path 数量太多的话字符串就会太长 超出了最大限制 就会这样 现在还真没什么好办法解决这个问题 实在不想放在代码程序里实现...
环境变量一般都很长,nas难道没考虑到这个吗,不应该吧
copilot给的回复是增大nas的缓冲区长度大小
在NSIS中处理包含中文字符的环境变量时,确实需要特别注意,因为NSIS默认使用ANSI编码,而中文字符在ANSI中可能会导致问题。为了确保正确处理中文字符,可以考虑以下几点:使用Unicode NSIS:Unicode NSIS能够更好地处理包含中文字符的字符串。确保使用的是Unicode版本的NSIS。字符串处理函数:确保字符串处理函数(如StrStr、UnStrStr、UnStrRep)能够正确处理包含中文字符的字符串。增加字符串缓冲区大小:通过定义NSIS_MAX_STRLEN来增加NSIS的字符串缓冲区大小,避免环境变量长度超限问题。
!define NSIS_MAX_STRLEN 8192 ; 增加字符串缓冲区大小到8192字符
!include "StrFunc.nsh"
${StrStr}
${UnStrStr}
${UnStrRep}
!macro NSIS_HOOK_POSTINSTALL
; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH%
ReadEnvStr $0 "HOMEDRIVE"
ReadEnvStr $1 "HOMEPATH"
StrCpy $1 "$0$1\.nvmd\bin"
; 读取系统范围的 PATH 环境变量
ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
StrCmp $2 "" 0 +2
StrCpy $2 "$2;"
; 检查目录是否在 PATH 中
${StrStr} $3 "$2" "$1"
StrCmp $3 "" 0 +3
; 如果目录不在 PATH 中,则添加
StrCpy $2 "$2$1"
; 更新注册表
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$2"
; 通知系统环境变量已更新
System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)'
!macroend
!macro NSIS_HOOK_PREUNINSTALL
; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH%
ReadEnvStr $0 "HOMEDRIVE"
ReadEnvStr $1 "HOMEPATH"
StrCpy $1 "$0$1\.nvmd\bin"
; 读取系统范围的 PATH 环境变量
ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
; 确保 $2 不为空
StrCmp $2 "" done
; 检查目录是否在 PATH 中
${UnStrStr} $3 "$2" "$1"
StrCmp $3 "" done
; 如果目录在 PATH 中,移除它
; 移除中间的路径
${UnStrRep} $4 "$2" "$1;" ""
${UnStrRep} $4 "$4" ";$1" "" ; 移除开始的路径
${UnStrRep} $4 "$4" "$1" "" ; 移除结尾的路径
; 移除多余的分号
${UnStrRep} $4 "$4" ";;" ";"
; 修复可能的前导和尾随分号
${UnStrRep} $4 "$4" "^;" "" ; 移除前导分号
${UnStrRep} $4 "$4" ";$" "" ; 移除尾随分号
; 更新注册表
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$4"
; 通知系统环境变量已更新
System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)'
done:
!macroend
老哥快解决一下
electron 版本的环境变量被 tauri 顶掉了,没有 nvmd 我要死了,救命啊,大佬
copilot给的回复是增大nas的缓冲区长度大小 在NSIS中处理包含中文字符的环境变量时,确实需要特别注意,因为NSIS默认使用ANSI编码,而中文字符在ANSI中可能会导致问题。为了确保正确处理中文字符,可以考虑以下几点:使用Unicode NSIS:Unicode NSIS能够更好地处理包含中文字符的字符串。确保使用的是Unicode版本的NSIS。字符串处理函数:确保字符串处理函数(如StrStr、UnStrStr、UnStrRep)能够正确处理包含中文字符的字符串。增加字符串缓冲区大小:通过定义NSIS_MAX_STRLEN来增加NSIS的字符串缓冲区大小,避免环境变量长度超限问题。
!define NSIS_MAX_STRLEN 8192 ; 增加字符串缓冲区大小到8192字符 !include "StrFunc.nsh" ${StrStr} ${UnStrStr} ${UnStrRep} !macro NSIS_HOOK_POSTINSTALL ; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; 读取系统范围的 PATH 环境变量 ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCmp $2 "" 0 +2 StrCpy $2 "$2;" ; 检查目录是否在 PATH 中 ${StrStr} $3 "$2" "$1" StrCmp $3 "" 0 +3 ; 如果目录不在 PATH 中,则添加 StrCpy $2 "$2$1" ; 更新注册表 WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$2" ; 通知系统环境变量已更新 System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' !macroend !macro NSIS_HOOK_PREUNINSTALL ; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; 读取系统范围的 PATH 环境变量 ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" ; 确保 $2 不为空 StrCmp $2 "" done ; 检查目录是否在 PATH 中 ${UnStrStr} $3 "$2" "$1" StrCmp $3 "" done ; 如果目录在 PATH 中,移除它 ; 移除中间的路径 ${UnStrRep} $4 "$2" "$1;" "" ${UnStrRep} $4 "$4" ";$1" "" ; 移除开始的路径 ${UnStrRep} $4 "$4" "$1" "" ; 移除结尾的路径 ; 移除多余的分号 ${UnStrRep} $4 "$4" ";;" ";" ; 修复可能的前导和尾随分号 ${UnStrRep} $4 "$4" "^;" "" ; 移除前导分号 ${UnStrRep} $4 "$4" ";$" "" ; 移除尾随分号 ; 更新注册表 WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$4" ; 通知系统环境变量已更新 System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' done: !macroend
这个办法也不可行
目前调研到了使用这个库来实现 https://github.com/awaescher/PathEd 有点工作量的 而且还在上班 所以需要一点点时间 还望见谅
copilot给的回复是增大nas的缓冲区长度大小 在NSIS中处理包含中文字符的环境变量时,确实需要特别注意,因为NSIS默认使用ANSI编码,而中文字符在ANSI中可能会导致问题。为了确保正确处理中文字符,可以考虑以下几点:使用Unicode NSIS:Unicode NSIS能够更好地处理包含中文字符的字符串。确保使用的是Unicode版本的NSIS。字符串处理函数:确保字符串处理函数(如StrStr、UnStrStr、UnStrRep)能够正确处理包含中文字符的字符串。增加字符串缓冲区大小:通过定义NSIS_MAX_STRLEN来增加NSIS的字符串缓冲区大小,避免环境变量长度超限问题。
!define NSIS_MAX_STRLEN 8192 ; 增加字符串缓冲区大小到8192字符 !include "StrFunc.nsh" ${StrStr} ${UnStrStr} ${UnStrRep} !macro NSIS_HOOK_POSTINSTALL ; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; 读取系统范围的 PATH 环境变量 ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCmp $2 "" 0 +2 StrCpy $2 "$2;" ; 检查目录是否在 PATH 中 ${StrStr} $3 "$2" "$1" StrCmp $3 "" 0 +3 ; 如果目录不在 PATH 中,则添加 StrCpy $2 "$2$1" ; 更新注册表 WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$2" ; 通知系统环境变量已更新 System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' !macroend !macro NSIS_HOOK_PREUNINSTALL ; 获取当前用户的 %HOMEDRIVE% 和 %HOMEPATH% ReadEnvStr $0 "HOMEDRIVE" ReadEnvStr $1 "HOMEPATH" StrCpy $1 "$0$1\.nvmd\bin" ; 读取系统范围的 PATH 环境变量 ReadRegStr $2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" ; 确保 $2 不为空 StrCmp $2 "" done ; 检查目录是否在 PATH 中 ${UnStrStr} $3 "$2" "$1" StrCmp $3 "" done ; 如果目录在 PATH 中,移除它 ; 移除中间的路径 ${UnStrRep} $4 "$2" "$1;" "" ${UnStrRep} $4 "$4" ";$1" "" ; 移除开始的路径 ${UnStrRep} $4 "$4" "$1" "" ; 移除结尾的路径 ; 移除多余的分号 ${UnStrRep} $4 "$4" ";;" ";" ; 修复可能的前导和尾随分号 ${UnStrRep} $4 "$4" "^;" "" ; 移除前导分号 ${UnStrRep} $4 "$4" ";$" "" ; 移除尾随分号 ; 更新注册表 WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$4" ; 通知系统环境变量已更新 System::Call 'KERNEL32::SendMessageTimeoutW(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, t "Environment", i 0x0, i 1000, *i 0)' done: !macroend
这个办法也不可行
目前调研到了使用这个库来实现 https://github.com/awaescher/PathEd 有点工作量的 而且还在上班 所以需要一点点时间 还望见谅
我等你,亲亲ლ(°◕‵ƹ′◕ლ)
验证过了 这个方案可行 目前在写一些ci的代码 没问题之后会重新发布
@lsrweb 已经发布了 你可以下载试试还会不会有问题
好,我试试
没问题,CLOSE