2015-06-28 12 views
6

Gibt es für VBScript eine %* (Batch-Dateien) oder $* (Bash-Skript) Argumentliste?

Ich möchte den genauen Aufruf der Befehlszeile abrufen.

konstruiertes Beispiel:

cscript //nologo script.vbs /arg1:a -s "a b" 1 c /arg2:"x y" "d e" -l '3 4' 

zurückkehren sollte:

/arg1:a -s "a b" 1 c /arg2:"x y" "d e" -l '3 4' 

(einschließlich der Anführungszeichen).

Ich habe WScript.Arguments betrachtet, aber es gibt nicht die Verbatim-Befehlszeile zurück.

Antwort

0

Es gibt keins. Aber es ist ziemlich trivial.

For each ag in wscript.arguments 
    CMDLINE = CMDLINE & " " & ag 
Next 
wscript.echo mid(CMDLINE, 2) 

oder

For each ag in wscript.arguments 
    If Instr(Ag, " ") = True then 
     CMDLINE = CMDLINE & " " & Chr(34) & ag & Chr(34) 
    Else 
     CMDLINE = CMDLINE & " " & ag 
    End if 
Next 
wscript.echo mid(CMDLINE, 2) 

Und

C:\Users\User>cscript //nologo "C:\Users\User\Desktop\New Text Document (3).vbs" cat dog "mouse and cat" 
cat dog mouse and cat 

Dies gilt für VBScript und VBA.

Diese beiden Grundlagen werden von anderen Programmen gehostet. Es ist der Host, der Befehlszeileninformationen sammelt (falls vorhanden). Es ist der Host, der es VBS über ein Objekt im Fall von wscript zur Verfügung stellt, aber nicht, wenn es in IE/IIS gehostet wird. Und VBA hat eine Host-implementierte Funktion (implementiert von Corel Office, Microsoft Office und VB6).

Function Declaration 
Function Command() As Variant 
Function Command$() As String 
Runtime Semantics. 
Returns the argument portion of the implementation dependent command used to initiate execution of the currently executing VBA program. 
The runtime semantics of Command$ are identical to those of Command with the exception that the declared type of the return value is String rather than Variant. 

Unter der Haube (Ich habe keine Parsingverhalten Absätze entfernt) (und beachten Sie ANSI/Unicode Unterschiede)

CommandLineToArgvW Funktion


Analysiert eine Unicode-Befehlszeilen-Zeichenfolge und kehrt ein Array von nullterminierten Unicode-Zeichenfolgen, die die einzelnen Argumente enthalten, die in dieser Befehlszeile gefunden werden, sowie eine Anzahl von Argumenten, ähnlich den Standard-Argov- und Argc-Werten für die Laufzeit in der Laufzeit.

Syntax

LPWSTR *CommandLineToArgvW(   LPCWSTR lpCmdLine, 
    int *pNumArgs 
); 

Parameter

Diese Funktion akzeptiert Linien Befehl einen Programmnamen enthält, die entweder in Anführungszeichen gesetzt ist oder nicht in Anführungszeichen eingeschlossen.

CommandLineToArgvW hat eine spezielle Auslegung der umgekehrten Schrägstrich-Zeichen, wenn sie von einem Anführungszeichen Zeichen gefolgt sind ("), wie folgt:

  • 2n Schrägstriche durch ein Anführungszeichen produzieren n Schrägstriche gefolgt durch ein Zitat folgte Markierung

    (2n) + 1 umgekehrte Schrägstriche gefolgt von einem Anführungszeichen wieder produzieren n Backslashes gefolgt von einem Anführungszeichen.

    n Backslashes nicht gefolgt von einem Anführungszeichen einfach produzieren n Backslashes.

GetCommandLine

Ruft die Befehlszeilenzeichenfolge für den aktuellen Prozess.

LPTSTR WINAPI GetCommandLine(void); 

ANSI Konsole Prozesse in C geschrieben wurde, kann die argc und argv Argumente der Hauptfunktion verwenden, um die Befehlszeilenargumente zuzugreifen. ANSI-GUI-Anwendungen können den LpCmdLine-Parameter der WinMain-Funktion verwenden, um auf die Befehlszeile-Zeichenfolge zuzugreifen, die den Programmname ausschließt. Der Grund dafür, dass main und WinMain keine Unicode-Zeichenfolgen zurückgeben können, liegt darin, dass argc, argv und lpCmdLine den LPSTR-Datentyp für Parameter und nicht den LPTSTR-Datentyp verwenden. Die Funktion GetCommandLine kann für den Zugriff auf Unicode-Zeichenfolgen verwendet werden, da sie den LPTSTR-Datentyp verwendet.

Um die Befehlszeile in ein argv-arrayarray zu konvertieren, rufen Sie die Funktion CommandLineToArgvW auf.

Hinweis Der Name der ausführbaren Datei in der Befehlszeile, die das Betriebssystem für einen Prozess bereitstellt, stimmt nicht unbedingt mit dem Namen in der Befehlszeile überein, die der aufrufende Prozess der CreateProcess-Funktion gibt. Das Betriebssystem kann einen vollständig qualifizierten Pfad einem ausführbaren Namen voranstellen, der ohne einen vollständig qualifizierten Pfad bereitgestellt wird.

+2

Argumente mit Leerzeichen müssen angegeben werden. –

+2

'Instr (Ag," ") = True" verstößt gegen die Regel "Nie mit True/False vergleichen" (http://blogs.msdn.com/b/ericlippert/archive/2004/07/15/184431.aspx) . –

+0

Ihr zweiter Codeblock benötigt ebenfalls ein 'End If'. – Bond

6

Es gibt kein Äquivalent zu %* oder $* in VBScript. Die WScript.Arguments-Auflistung blendet die Eingabe-Befehlszeile aus und ermöglicht den Zugriff auf die Argumente als Elemente in Sammlungen.

Die einzige Möglichkeit, die erforderlichen Informationen abzurufen, besteht darin, WMI für den aktuellen Prozess abzufragen und über die Befehlszeile die Prozessinformationen zu lesen.

Dies gibt Ihnen die vollständige Befehlszeile zum Starten des aktuellen Skripts.

Option Explicit 

' We need a child process to locate the current script. 
Const FLAG_PROCESS = "winver.exe" 

' WMI constants 
Const wbemFlagForwardOnly = 32 

' Generate a unique value to be used as a flag 
Dim guid 
    guid = Left(CreateObject("Scriptlet.TypeLib").GUID,38) 

' Start a process using the indicated flag inside its command line 
    WScript.CreateObject("WScript.Shell").Run """" & FLAG_PROCESS & """ " & guid, 0, False 

' To retrieve process information a WMI reference is needed  
Dim wmi 
    Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 

' Query the list of processes with the flag in its command line, retrieve the 
' process ID of its parent process (our script!) and terminate the process 
Dim colProcess, process, myProcessID 
    Set colProcess = wmi.ExecQuery(_ 
     "SELECT ParentProcessID From Win32_Process " & _ 
     "WHERE Name='" & FLAG_PROCESS & "' " & _ 
     "AND CommandLine LIKE '%" & guid & "%'" _ 
     ,"WQL" , wbemFlagForwardOnly _ 
    ) 
    For Each process In colProcess 
     myProcessID = process.ParentProcessID 
     process.Terminate 
    Next 

' Knowing the process id of our script we can query the process list 
' and retrieve its command line 
Dim commandLine 
    set colProcess = wmi.ExecQuery(_ 
     "SELECT CommandLine From Win32_Process " & _ 
     "WHERE ProcessID=" & myProcessID _ 
     ,"WQL" , wbemFlagForwardOnly _ 
    ) 
    For Each process In colProcess 
     commandLine = process.CommandLine 
    Next 

' Done 
    WScript.Echo commandLine 
+0

Das ist eine nette Idee. Aber das Erstellen und Beenden eines neuen Prozesses und das Ausführen von zwei WMI-Abfragen scheint nur ein Overkill zu sein, anstatt die Strings in der 'WScript.Arguments'-Sammlung zu verketten. – Bond

+2

@Bond, ja, es ist nicht der einfachste Weg, es zu tun, aber die Verkettung von Argumenten wird nicht den Unterschied zwischen '/ test:" data "' und '/ test: data' oder'/test: "da" ta "'. Oder '/ test:" da \ "ta" 'und'/test: "da \ ta" 'Argumente Sammlung wird alle doppelten Anführungszeichen entfernen, und OP angegeben, dass Zitate enthalten sein sollten. –

+1

Sie haben Recht. Get's meine Stimme (Obwohl OP verstehen sollte, wie ARGs in WSH arbeiten und versuchen, diese Art von Situationen zu vermeiden) – Bond

Verwandte Themen