这将比较原始的
cmd
环境(保存到文件中)和当前环境。如果需要不同的检查,您可以更改文件创建方式。
@echo off
setlocal enableextensions disabledelayedexpansion
for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (
start /i /wait /min "" "%comspec%" /c">""%%~ff"" set "
for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (
set "%%d="
for /f "delims= eol==" %%a in ('set') do (
set "%%e="
for /f "usebackq delims= eol==" %%o in ("%%~ff") do (
if %%a==%%o ( set "%%e=1" ) else if not defined %%d (
for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=)
)
)
if not defined %%e (echo(%%a)
) & if not defined %%d set "%%d=1"
) & set "%%d=" & set "%%e="
) & del "%%~ff"
一旦我们去掉注释,代码量并不像看起来那么多。
@echo off
setlocal enableextensions disabledelayedexpansion
for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (
start /i /wait /min "" "%comspec%" /c">""%%~ff"" set "
for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (
set "%%d="
for /f "delims= eol==" %%a in ('set') do (
set "%%e="
for /f "usebackq delims= eol==" %%o in ("%%~ff") do (
if %%a==%%o ( set "%%e=1" ) else if not defined %%d (
for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=)
)
)
if not defined %%e (echo(%%a)
) & if not defined %%d set "%%d=1"
) & set "%%d=" & set "%%e="
) & del "%%~ff"
edited仅供完整性。正如dbenham所指出的,以前的代码无法处理变量名称或值中带有换行符的变量。这是一个混合的批处理文件(保存为例如checkEnvironment.cmd
文件),可以处理这种情况。
@if (@This==@IsBatch) @then /* Batch zone ------------------------------------
@echo off
setlocal enableextensions disabledelayedexpansion
call :processCurrentEnvironment "%~f1"
goto :eof
:processCurrentEnvironment
call "%systemroot%\system32\cscript.exe" //nologo //e:JScript "%~f0" /saved:"%~1"
goto :eof
*/ @end
// Javascript zone -----------------------------------------------------------
var environment = WScript.CreateObject('WScript.Shell').Environment('PROCESS');
var savedFileName = WScript.Arguments.Named.Item('saved');
if ( !savedFileName ){
// If no saved file name present, output current environment
for ( var e = new Enumerator(environment); !e.atEnd(); e.moveNext()){
WScript.StdOut.Write( e.item() + '\0\r\n' );
};
} else {
// Retrieve saved environment to compare against current one
var savedEnvironment = retrieveSavedEnvironment( savedFileName );
// For each element in the current environment
for ( var e = new Enumerator(environment); !e.atEnd(); e.moveNext() ) {
// retrieve { variable: , value: } representation of the variable
var buffer = splitEnvironmentVariable( e.item() );
if ( buffer ) {
// if the current variable does not exist in the saved version
// or if the current value does not match the previous one
// then dump the current variable
if (
! savedEnvironment[buffer.variable]
|| savedEnvironment[buffer.variable].value !== buffer.value
) outputVariable( buffer );
// in any case, this is a processed variable
delete savedEnvironment[buffer.variable];
}
};
// any saved variables still present are deleted variables, show them
for (var e in savedEnvironment) outputVariable( e );
};
// - Helper functions ----------------------------------------------------------
// Process the contents of the saved file to generate a { {variable: , value: }, ... }
// representation of the saved environment
function retrieveSavedEnvironment( savedFileName ) {
var savedEnvironment = {};
var buffer = readFile( savedFileName ).split('\0\r\n');
for (var i in buffer) if ( buffer[i] = splitEnvironmentVariable(buffer[i]) ) {
savedEnvironment[buffer[i].variable] = buffer[i];
};
return ( savedEnvironment );
};
// Read the contents of the saved file - FSO can not be used because we are
// writing nulls (ascii 0x00 character) to separate variables
function readFile( savedFileName ){
var buffer = "";
if (
WScript.CreateObject('Scripting.FileSystemObject').FileExists( savedFileName )
){
var stream = WScript.CreateObject('ADODB.Stream');
stream.Open();
stream.Type = 2
stream.Charset = 'ascii';
stream.LoadFromFile( savedFileName );
buffer = stream.ReadText();
stream.Close();
};
return ( buffer );
};
// Convert variable=value to { variable: , value: }
function splitEnvironmentVariable( text ){
text = (/^([\s\S][^=]*)=([\s\S]+)/).exec( text );
return (
text
? { variable : text[1] , value : text[2] }
: text
);
};
// Write the variable with its value or only the variable name
function outputVariable( variable ){
if ( typeof variable === 'object' ) {
WScript.StdOut.WriteLine( variable.variable + '=' + variable.value );
} else {
WScript.StdOut.WriteLine( variable + '=' );
};
};
将它放置在批处理文件的路径或同一文件夹中,您可以将其用作
@echo off
setlocal enableextensions enabledelayedexpansion
(SET LF=^
%=this line is empty=%
)
set "variableToDelete=1"
set "my!lf!var1=my!lf!data"
set "originalEnvironment=%temp%\original_%random%%random%%random%.tmp"
>"%originalEnvironment%" call checkEnvironment.cmd
set "thisIsNew=value"
set "anotherOne=1"
set "my!lf!var2=my!lf!data"
set "variableToDelete="
set "my!lf!var1="
call checkEnvironment.cmd "%originalEnvironment%"
del /q "%originalEnvironment%"
获得退出的方法是
W:\>testEnv.cmd
anotherOne=1
my
var2=my
data
thisIsNew=value
my
var1=
variableToDelete=
W:\>
find
或findstr
查找该模式会更容易。但即使如此,已经存在的变量的更改也无法被检测到。也许 OP 可以提供更多规格说明。 - J.Baoby