34

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!
Community
  • 1
  • 1
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
  • 1
    there's a vote to close this question, I'm curious why. What about it is uninteresting/worthy? – matt wilkie Nov 25 '11 at 07:43
  • 2
    The user who has voted to close your question is merely suggesting that it is off-topic here and belongs on http://superuser.com/ – Andriy M Nov 25 '11 at 18:20
  • Yes, that was me, I thought it would be better at superuser. Clearly I have been outvoted though! :) – Cam Jackson Feb 02 '12 at 23:18

6 Answers6

18

Anders' recipe has detailed control over a new environment, and I'm leaving that as the accepted answer because of that depth control. However one phrase in that answer led to me the method I'll actually be using for the particular problem which prompted this enquiry. An "environment that is equal to the initial explorer.exe environment". Oh! I know how to do that!

start /i "%windir%\explorer.exe" "%windir%\system32\cmd.exe"

Note: originally this was simply start /i explorer ..., but it turns out that doesn't work reliably, and a full path should be be used for both parts. If all you need is a solution, you have everything now and can ignore the rest.


Following Ander's comment below about a security warning I tested on 4 Win7 computers, a mix of Pro, Home, and Enterprise, 32 and 64bit. I fiddled with User Account Control, all the way up and all the way down. Also tested with a non-administrator Command Prompt shell. These all worked without error or warning.

On Server 2003, logged on as local administrator, I get a popup dialog "File Download - Security Warning: do you want to run or save this file?" with buttons for run,save, and cancel. Pressing [run] results in an additional dialog, "Windows Explorer - Security Warning: the publisher could not be verified. Are you sure you want to run this software?". Pressing [run] again finally results in a usable command shell. Apparently there is some weird logic that results in Internet Explorer being substituted for Windows Explorer without the full path to the exe.

It gets even stranger though: using start with a title, (some advise to always include a title) results in the security warnings regardless of full path. Other parameters like starting directory seem to be okay.

:: 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"
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
  • 1
    That is not supported explorer syntax AFAIK and when I tried it I got a security warning. – Anders Nov 27 '11 at 02:35
  • Is the `/I` option really needed with this solution? I think explorer.exe will initiate default values either way. – dbenham Mar 04 '17 at 16:06
6

If you're willing to use powershell, you can use:

Start-Process -UseNewEnvironment powershell

or

Start-Process -UseNewEnvironment cmd

Caleb Jares
  • 6,163
  • 6
  • 56
  • 83
6

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...

Anders
  • 97,548
  • 12
  • 110
  • 164
  • 1
    Why not simply do `start/i %windir%/explorer "%windir%\system32\cmd.exe"`? – Pacerier Mar 04 '17 at 09:28
  • @Pacerier It is technically not valid Explorer syntax even though it seems to work. See the answer below for how to work around a security warning. – Anders Mar 04 '17 at 15:54
5

I'm not aware of a way to do it in the same window. But you can accomplish the task in a separate window using

start /i cmd

If you want your current cmd session to wait until the new session ends you can add the /wait option

EDIT

I stand corrected, thanks to Romário's comment. You can add the /B and /WAIT options to create the new cmd.exe session in the same window.

start /i /b /wait cmd

Note that the new cmd.exe inherits the initial environment that existed when the parent was launched. It may not be the default environment if the parent was itself launched from another cmd.exe environment.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • okay, that is a partial solution for me, a new window is not a deal breaker. It does reveal that my initial question did not contain enough info though. I need to start a clean *system default* environment, my parent shell is not system default and has settings that are inherited in the `start /i cmd` shell that shouldn't be. I'll update the Q accordingly. – matt wilkie Nov 25 '11 at 00:02
  • You can put it in the same window using the `/b` switch. – Romário Mar 21 '16 at 13:53
  • @Romário - Of course! I don't know why I didn't think to combine the `/I` and `/B` options. But you probably want the `/WAIT` option as well, else the shared console becomes very confusing. – dbenham Mar 21 '16 at 15:30
  • `start /i cmd` still retains the original %path% of the parent cmd window isn't it? That's not what the quesiton wanted. – Pacerier Mar 04 '17 at 09:30
  • @Pacerier - The PATH variable is no different than any other variable. The new cmd session will ignore the current environment of the parent session, and instead use the values that existed when the parent session was started. I have already acknowledged that this is not exactly what the OP was looking for because the parent session may not have been started with default values. But this answer was a step in the right direction, and it is adequate in many situations. – dbenham Mar 04 '17 at 16:02
1

A sample below of how I got this working for me.

@ECHO OFF
TITLE Test
SET SELF=%~dp0%~n0%~x0

ECHO SetVar : %VAR1%
PAUSE
SETX VAR1 "Random Value"
WMIC PROCESS CALL CREATE "%SELF%"
EXIT 0
Les Butler
  • 11
  • 1
-1

This looks like an old post, but this is what I tried:

start /i

this link has more info: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true

That command should open a new window which is like the startup cmd environment.