如果我从现有shell启动新的CMD shell,则新shell将继承现有环境.有没有办法启动一个新的shell,但它已初始化为系统默认值而不是继承?
目前的结果:
B:\>set _test=blooharky
B:\>cmd
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
B:\>set _
_test=blooharky
Run Code Online (Sandbox Code Playgroud)
期望的结果:
B:\>set _test=blooharky
B:\>cmd /env=default
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
B:\>set _
Environment variable _ not defined
Run Code Online (Sandbox Code Playgroud)
[更新]此解决方案start /i cmd由dbenham共享,如下所示.但是,在当前shell已经是第二代的情况下它没有帮助.例:
d:\>set _
Environment variable _ not defined
d:\>set _test=blooharky
d:\>cmd /k
:: some work done using _test here...
:: ...but after we need a new clean shell:
d:\>start /i cmd
d:\>set _
_test=blooharky
:: uhoh, our shell isn't clean!
Run Code Online (Sandbox Code Playgroud)
mat*_*kie 16
安德斯的配方对新环境进行了详细的控制,由于深度控制,我将其作为公认的答案.然而,该答案中的一个短语导致了我实际用于促进此查询的特定问题的方法.一个"环境即等于初始Explorer.exe的环境".哦! 我知道该怎么做那个!
start /i "%windir%\explorer.exe" "%windir%\system32\cmd.exe"
Run Code Online (Sandbox Code Playgroud)
注意:最初这很简单start /i explorer ...,但事实证明它不能可靠地工作,并且应该为两个部分使用完整路径.如果你需要的只是一个解决方案,你现在拥有一切,可以忽略其余的一切.
下面是Ander关于我在4台Win7计算机上测试的安全警告的评论,这是Pro,Home和Enterprise的混合,32位和64位.我摆弄着用户帐户控制,一路向上,一路向下.还使用非管理员命令提示符shell进行了测试.这些都没有错误或警告.
在Server 2003上,以本地管理员身份登录,我得到一个弹出对话框"文件下载 - 安全警告:您要运行还是保存此文件?" 带有用于运行,保存和取消的按钮.按[run]会产生一个额外的对话框,"Windows资源管理器 - 安全警告:无法验证发布者.您确定要运行此软件吗?" .再次按[run]最终会生成一个可用的命令shell.显然有一些奇怪的逻辑导致Internet Explorer被替换为Windows资源管理器而没有exe的完整路径.
它甚至变得更加奇怪:使用start标题,(一些建议总是包括atitle)会导致安全警告,无论完整路径如何.其他参数如启动目录似乎没问题.
:: security warning
start "clean shell" /i "%windir%\explorer.exe" "%windir%\system32\cmd.exe"
:: is okay
start /i /d x:\ "%windir%\explorer.exe" "%windir%\system32\cmd.exe"
Run Code Online (Sandbox Code Playgroud)
我不知道在同一个窗口中执行此操作的方法。但是您可以使用以下命令在单独的窗口中完成任务
\n\nstart /i cmd\nRun Code Online (Sandbox Code Playgroud)\n\n如果您希望当前的 cmd 会话等到新会话结束,您可以添加该/wait选项
编辑
\n\n感谢 Rom\xc3\xa1rio 的评论,我得到了纠正。您可以添加/B and /WAIT选项以在同一窗口中创建新的 cmd.exe 会话。
start /i /b /wait cmd\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,新的 cmd.exe 继承了启动父级时存在的初始环境。如果父环境本身是从另一个 cmd.exe 环境启动的,则它可能不是默认环境。
\n一些变量在登录时初始化,不与其他注册表项一起存储,因此如果您想要一个与初始 explorer.exe 环境相同的环境,您需要将这些项目列入白名单,并希望它们没有被任何人更改:
@echo off
setlocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
goto main
:SetFromReg
FOR /F "tokens=2,*" %%A IN ('REG query "%~1" /v "%~2"^|find /I "REG_"') DO (
call set %~3=%%B
)
goto :EOF
:GetRegEnv
FOR /F %%A IN ('REG query "%~1" /s^|find /I "REG_"') DO (
if /I not "%%~A"=="Path" call :SetFromReg "%~1" "%%~A" "%%~A"
)
goto :EOF
:InheritOrDelete
for %%A in (save_TEMP Path SystemRoot SystemDrive ProgramFiles CommonProgramFiles ALLUSERSPROFILE COMPUTERNAME LOGONSERVER USERNAME USERDOMAIN HOMEDRIVE HOMEPATH USERPROFILE APPDATA) do if /I "%%~A"=="%~1" goto :EOF
set %~1=
goto :EOF
:main
REM Save temp
set save_TEMP=%temp%
if not defined save_TEMP set save_TEMP=%tmp%
for /F "delims==" %%A in ('set') do call :InheritOrDelete "%%~A"
call :GetRegEnv "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
call :GetRegEnv "HKCU\Environment"
REM Special handling for Path
call :SetFromReg "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" Path Path
setlocal
set u=
call :SetFromReg "HKCU\Environment" Path u
endlocal&if not "%Path%"=="" if not "%u%"=="" set Path=%Path%;%u%
REM Restore TEMP/TMP
set TEMP=%save_TEMP%
set save_TEMP=
set TMP=%TEMP%
REM start some command...
start cmd /d /k set
Run Code Online (Sandbox Code Playgroud)
reg.exe 的输出在每个 Windows 版本上都不相同,因此您必须确保它在您的目标系统上工作(如果变量的名称包含空格,它也会出现问题,您可以通过替换来解决这个问题"tokens=2,*"with "tokens=2,* delims= "(delims equals tab) 但在此之前请确保 reg.exe 输出始终使用 tab 作为分隔符)
您可以通过使用 Windows 脚本宿主脚本而不是批处理文件来解决这些问题:
'orgenvshell.vbs:
Set WShl = CreateObject( "WScript.Shell" )
Set FSO = CreateObject("Scripting.FileSystemObject")
Function CanInherit(n)
CanInherit = False
w = Split("SystemRoot SystemDrive ProgramFiles CommonProgramFiles ALLUSERSPROFILE COMPUTERNAME LOGONSERVER USERNAME USERDOMAIN HOMEDRIVE HOMEPATH USERPROFILE APPDATA")
For Each i In w
If 0 = StrComp(i,n,1) Then
CanInherit = True
Exit Function
End If
Next
End Function
Function GetShortFolderPath(p)
GetShortFolderPath = p
On Error Resume Next
GetShortFolderPath = FSO.GetFolder(p).ShortPath
End Function
Sub E(dst,src)
set envs = WShl.Environment(src)
For Each i In envs
t = Split(i,"=")
n = t(0)
If n = "" Then n = "="&t(1)
If IsNull(dst) Then
If not CanInherit(n) Then envs.Remove n
Else
v = Mid(i,Len(n)+2)
envd = dst
If "X" = dst Then
v = WShl.ExpandEnvironmentStrings(v)
envd = src
If 0 = StrComp(n,"TMP",1) Then v = GetShortFolderPath(v)
If 0 = StrComp(n,"TEMP",1) Then v = GetShortFolderPath(v)
End If
WShl.Environment(envd)(n) = v
End If
Next
End Sub
E Null,"PROCESS"
E "PROCESS","SYSTEM"
E "PROCESS","USER"
E "X","PROCESS"
'Special hack for Path
s = WShl.Environment("SYSTEM")("Path")
u = WShl.Environment("USER")("Path")
If Len(u) Then s = s&";"&u
WShl.Environment("PROCESS")("Path") = WShl.ExpandEnvironmentStrings(s)
'Test a command
WShl.Run "cmd /d /k set ",1
Run Code Online (Sandbox Code Playgroud)
您可能可以通过查询 WMI 和使用其他 WSH 方法来删除许多列入白名单的项目......
如果你愿意使用powershell,你可以使用:
Start-Process -UseNewEnvironment powershell
或者
Start-Process -UseNewEnvironment cmd