开始新的CMD.EXE和不能承受的环境? [英] Start new cmd.exe and NOT inherit environment?

查看:170
本文介绍了开始新的CMD.EXE和不能承受的环境?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我从现有shell启动一个新的CMD外壳,新的外壳继承了现有的环境。是否有一个启动一个新的外壳,但有它初始化为系统默认值,而不是继承的方式?

当前的结果:

  B:\\>设置_test = blooharkyA:\\> CMD
微软的Windows [版本6.1.7600]
版权所有(c)2009年微软公司。版权所有。A:\\>设置_
_test = blooharky

期望的结果:

  B:\\>设置_test = blooharkyA:\\> CMD / ENV =默认
微软的Windows [版本6.1.7600]
版权所有(c)2009年微软公司。版权所有。A:\\>设置_
_没有定义环境变量

[更新] 解决方案这是启动/ I CMD ,由dbenham共享的下面。然而,它没有在当前shell已经是第二代的情况有所帮助。例如:

  D:\\>设置_
_没有定义环境变量D:\\>设置_test = blooharkyD:\\> CMD / K::一些工作用_test在这里完成...
:: ...但之后我们需要一个新的干净的壳:D:\\>开始/我CMDD:\\>设置_
_test = blooharky:: uhoh,我们的外壳不干净!


解决方案

有些变量在登录时被初始化,不存储与其他注册表项,所以如果你想要一个环境,就是等于初始环境的explorer.exe你需要白名单的项目,并希望他们没有被任何人更改:

 关闭@echo
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
转到主:SetFromReg
FOR / F令牌= 2 *%% A IN('REG查询%〜1/ V%〜2^ |找到/ IREG_')DO(
    设置呼叫%〜3%=%乙

GOTO:EOF:GetRegEnv
FOR / F %% A IN('REG查询%〜1/ S ^ |找到/ IREG_')DO(
    如果/没有我%%〜A==路径电话:SetFromReg%〜1%%〜A%%〜A

GOTO:EOF:InheritOrDelete
对于%%的(save_TEMP路径SYSTEMROOT系统驱动器PROGRAMFILES COMMONPROGRAMFILES ALLUSERSPROFILE COMPUTERNAME LOGONSERVER USERNAME USERDOMAIN HOMEDRIVE HOMEPATH USERPROFILE APPDATA)在做,如果/ I%%〜A==%〜1GOTO:EOF
设置%〜1 =
GOTO:EOF:主要
REM保存温度
设置save_TEMP =%TEMP%
如果没有定义save_TEMP设置save_TEMP =%TMP%FOR / Fdelims ==%%的(设定)一个做电:InheritOrDelete%%〜A
拨打:GetRegEnvHKLM \\系统\\ CurrentControlSet \\控制\\会话管理\\环境
拨打:GetRegEnvHKCU \\环境REM特殊处理路径
拨打:SetFromRegHKLM \\系统\\ CurrentControlSet \\控制\\会话管理\\环境路径路径
SETLOCAL
集U =
拨打:SetFromRegHKCU \\环境路径ü
ENDLOCAL&放大器;如果不是%PATH%==如果不是%U%==设置路径=%PATH%;%U%REM恢复TEMP / TMP
SET TEMP =%save_TEMP%
设置save_TEMP =
设置TMP =%TEMP%REM启动一些命令
启动CMD / D / K组

这REG.EXE的输出是不是每一个Windows版本一样的,所以你必须确保它的工作原理在目标系统上(它也有问题,如果一个变量的名称包含空格,你可以修复通过替换令牌= 2 *令牌= 2 * delims =(delims等于标签),但在此之前你做,请确保REG.EXE输出始终使用标签作为分隔符)

您可以通过使用Windows脚本宿主脚本,而不是一个批处理文件的解决这些问题:

 'orgenvshell.vbs:
设置WShl =的CreateObject(WScript.Shell)
设置FSO =的CreateObject(Scripting.FileSystemObject的)功能CanInherit(N)
    CanInherit = FALSE
    W =斯普利特(SYSTEMROOT系统驱动器PROGRAMFILES COMMONPROGRAMFILES ALLUSERSPROFILE COMPUTERNAME LOGONSERVER USERNAME USERDOMAIN HOMEDRIVE HOMEPATH USERPROFILE APPDATA)
    每个I为W
        如果0 = STRCOMP(I,N,1)。然后
            CanInherit = TRUE
            退出功能
        万一
    下一个
结束功能功能GetShortFolderPath(p)的
    GetShortFolderPath = P
    在错误恢复下一页
    GetShortFolderPath = FSO.GetFolder(p)的.ShortPath
结束功能子E(DST,SRC)
    设置ENVS = WShl.Environment(SRC)
    对于每一个我在ENVS
        T =斯普利特(我,=)
        N = T(0)
        如果n =,则n ==& T公司(1)
        如果ISNULL(DST)然后
            如果不是CanInherit(N)然后envs.Removeñ
        其他
            V = MID(I,莱恩(N)+2)
            envd将DST =
            如果X= DST然后
                V = WShl.ExpandEnvironmentStrings(v)的
                envd将SRC =
                如果0 = STRCOMP(正,TMP,1)则V = GetShortFolderPath(v)的
                如果0 = STRCOMP(N,TEMP,1)则V = GetShortFolderPath(V)
            万一
            WShl.Environment(envd将)(n)的= V
        万一
    下一个
结束小组E缺失,过程
E进程,SYSTEM
E进程,USER
EX,过程特殊的破解路径
S = WShl.Environment(SYSTEM)(路径)
U = WShl.Environment(USER)(路径)
如果len(U)则s = S&放大器;&放大器;ü
WShl.Environment(过程)(路径)= WShl.ExpandEnvironmentStrings(S)测试命令
WShl.RunCMD / D / K集,1

您可以通过查询WMI和使用其他方法WSH可能删除了很多白色的上市项目...

If I start a new CMD shell from an existing shell, the new shell inherits the existing environment. Is there a way to start a new shell but have it initialized to the system defaults and not inherit?

Current result:

B:\>set _test=blooharky

B:\>cmd
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

B:\>set _
_test=blooharky

Desired result:

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

[update] Solution for this is start /i cmd, as shared by dbenham, below. However it doesn't help in the situation where the current shell is already second generation. Example:

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!

解决方案

Some of the variables are initialized at logon and are not stored with the other registry entries so if you want a environment that is equal to the initial explorer.exe environment you need to white-list those items and hope they have not been changed by anyone:

@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

The output from reg.exe is not the same on every windows version so you would have to make sure that it works on your target system (It will also have problems if the name of a variable contains a space, you could fix that by replacing "tokens=2,*" with "tokens=2,* delims= " (delims equals tab) but before you do that make sure that the reg.exe output always uses tab as the separator)

You can work around these issues by using a windows scripting host script instead of a batch file:

'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

You could probably remove a lot of the white-listed items by querying WMI and using other WSH methods...

这篇关于开始新的CMD.EXE和不能承受的环境?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆