在某些情况下,确定双引号是否作为参数传递给WSH脚本很重要。例如,因为它们应该传递给另一个可运行的可执行文件。
标准解析函数/对象:
objArgs = WScript.Arguments;
for (i = 0; i < objArgs.length; i++)
{
WScript.Echo(objArgs(i));
}
不区分:
cscript foo.js "bar"
和
cscript foo.js bar
是否可以采用其他方法?
注意:我还尝试使用以下几种组合来逃避它们:
cscript foo.js '"bar"'
似乎他们被剥夺了。
答案 0 :(得分:2)
关注@ Ekkehard.Horner建议:
// parseArgs.js
// Parsing jscript script arguments verbatim
var Shell = new ActiveXObject("WScript.Shell"),
wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2"),
guid = (new ActiveXObject("Scriptlet.TypeLib")).GUID.substring(0,38),
windir=Shell.ExpandEnvironmentStrings("%WinDir%"),
winver="\"" + windir + "\\System32\\winver.exe\" " + guid,
pcol, pid, cmd;
// Run winver.exe hidden and get this script ID as its ParentProcessId
winver=winver.replace(/\\/g, "\\\\");
Shell.Run("winver " + guid, 0);
pcol = new Enumerator (wmi.ExecQuery(
"SELECT * From Win32_Process WHERE CommandLine='"+ winver + "'",
"WQL", 32));
for (; !pcol.atEnd(); pcol.moveNext()){
var prc = pcol.item();
pid=prc.ParentProcessId;
prc.Terminate;
}
// Get the command line for the found PID
pcol = new Enumerator (wmi.ExecQuery(
"SELECT * From Win32_Process WHERE ProcessID="+ pid,
"WQL", 32));
for (; !pcol.atEnd(); pcol.moveNext()){
var prc = pcol.item();
cmd =prc.CommandLine;
}
WScript.Echo(cmd);
// Parse command line for arguments
var ags,
parseCmd=function(cmd){// WMI trims initial spaces
var p = new Object(),
re =/^"/.test(cmd) ? /"[^"]+" */ : /\S+\s*/;
p.nxt=re.test(cmd) ? cmd.match(re)[0] : ""; // extract next token
p.rst=cmd.replace(re, "") ; // remainder
return(p);
}
// Strip c/wscript path
ags=parseCmd(cmd).rst
//WScript.Echo(ags);
// Remove WSH "//xxx" options
ags=ags.replace(/\/\/\w+ +/g, "")
//WScript.Echo(ags);
// Strip script name and get arguments
ags=parseCmd(ags).rst
WScript.Echo(ags);
// Loop args and store as an array
var i=1, aags=[];
while(ags != ""){
var p =parseCmd(ags);
ags=p.rst;
aags.push(p.nxt.replace(/ +$/, ""));
WScript.Echo(i, p.nxt);
i++;
}
WScript.Echo(aags);
正在运行parseArgs.js
:
> cscript //nologo parseArgs.js "hello" world
cscript //nologo parseArgs.js "hello" world
"hello" world
1 "hello"
2 world
"hello",world
该行:
> parseArgs.js "hello" world
给出了类似的结果。
我们需要这样一个令人费解的脚本吗?简答:不。长:依赖。
通常,假设您在运行脚本时知道脚本的名称,可以查询WMI
无论如何,在部署脚本时,通常无法控制deploy目录。因此,如果有另一个脚本以相同的名称运行,您无法确定哪一个是您的。
另一个不太边缘的情况是当你的脚本有两个或更多实例运行时。
这里的策略是隐藏一些虚拟标准Windows可执行文件(winver.exe
),并向其传递一个GUID。通过这种方式,可以安全地通过唯一GUID标识winver.exe
命令行,从而将您的脚本标识为winver.exe
的父级。
winver.exe
不需要参数,但如果你传递一些参数就不会抗议。