2011-01-14 34 views
16

Phương pháp stackoverflow được chấp thuận (và do đó chính xác) là gì để buộc VBS chạy bằng cscript thay vì wscript - bất kể người dùng cố gắng gì? Một tìm kiếm Google nhanh chóng cho thấy rất nhiều ví dụ, nhưng một số trong số họ chỉ đơn giản là không làm việc và những người thường không xử lý thực tế rằng nó có thể đã được chạy với các đối số vì vậy tôi muốn biết những gì cách tốt nhất là.Buộc VBS chạy bằng cscript thay vì wscript

Dưới đây là một ví dụ mà không xử lý đối số:

sExecutable = LCase(Mid(Wscript.FullName, InstrRev(Wscript.FullName,"\")+1)) 
If sExecutable <> "cscript.exe" Then 
    Set oShell = CreateObject("wscript.shell") 
    oShell.Run "cscript.exe """ & Wscript.ScriptFullName & """" 
    Wscript.Quit 
End If 

Tôi đánh giá cao rằng điều này có lẽ dễ dàng sửa đổi để xử lý đối số, nhưng nhận ra rằng điều này có thể không phải là cách tốt nhất để tiếp cận vấn đề.

Bối cảnh: Tôi đang viết một tập lệnh có thể chạy bằng cách nhấp đúp hoặc (rất có thể) từ tệp lô DOS hoặc làm tác vụ được lên lịch. Nó có thể chứa một hoặc nhiều đối số dòng lệnh tùy chọn.

+0

Thêm việc xử lý WScript.Arguments và bạn đã đặt. –

+0

@Kyle: nghe như một câu trả lời cho tôi không phải là một bình luận. – AnthonyWJones

+0

Dường như bạn đã tự trả lời, tôi vừa xác nhận. –

Trả lời

19

Chúa ơi, những gì không được pha trộn rác rưởi. Nó làm cho tôi khóc khi thấy mã hóa bùn như vậy (không có hành vi phạm tội đối với bất kỳ ai, lol). Nghiêm túc, tuy nhiên, đây là 2 xu của tôi:

Sub forceCScriptExecution 
    Dim Arg, Str 
    If Not LCase(Right(WScript.FullName, 12)) = "\cscript.exe" Then 
     For Each Arg In WScript.Arguments 
      If InStr(Arg, " ") Then Arg = """" & Arg & """" 
      Str = Str & " " & Arg 
     Next 
     CreateObject("WScript.Shell").Run _ 
      "cscript //nologo """ & _ 
      WScript.ScriptFullName & _ 
      """ " & Str 
     WScript.Quit 
    End If 
End Sub 
forceCScriptExecution 

Nó xử lý đối số, và kiểm tra các khoảng trống trong nói lý lẽ - vì vậy mà trong trường hợp của một tên tập tin thông qua với các trường hợp kịch bản gốc có chứa khoảng trắng, nó wouldn' t nhận được "tokenized" khi được chuyển đến cscript.exe.

Điều duy nhất nó không làm là kiểm tra cho StdIn (ví dụ, trong trường hợp ai đó đường dẫn một cái gì đó đến tập lệnh thông qua dòng lệnh, nhưng quên sử dụng "cscript script.vbs") - nhưng nếu nó được được thực thi bởi WScript.exe, các phương thức của WScript.StdIn đều trả về các lỗi Xử lý không hợp lệ, vì vậy không có cách nào để kiểm tra.

Vui lòng cho tôi biết nếu có cách "phá vỡ" điều này; Tôi sẵn sàng cải thiện nó nếu cần thiết.

+1

Sử dụng tốt nhất '// nologo' và được nhớ rõ về thử nghiệm không gian (và sau đó thêm dấu ngoặc kép) cho mỗi đối số. – Richard

+1

Dòng CreateObject thiếu dấu cách giữa tên tập lệnh và đối số. Như vậy, lệnh chạy không thành công. Để khắc phục, thay đổi 'WScript.ScriptFullName &" "" "& Str' thành' WScript.ScriptFullName & "" "" & Str'. – Richard

+1

FYI: Tôi đã chỉnh sửa tập lệnh để bao gồm khoảng trắng/thêm ngắt dòng để hiển thị mã tốt hơn trên trang web. Tuy nhiên tôi chỉ nhận ra không gian không bị thiếu - trong suốt không gian vòng lặp được tiền tố trên tất cả các đối số. Cũng như tách các đối số với nhau, đầu tiên trong số này tách chúng ra khỏi tên kịch bản. – JohnLBevan

1

Một cách tiếp cận có thể là cung cấp cho nó một tiện ích khác thay vì .vbs. Nói ví dụ .cvbs. Liên kết .cvbs với cscript.exe không phải wscript.exe, cách đó thực hiện hoặc nhấp đúp vào tệp .cvbs sẽ không bao giờ gọi wscript.exe.

+0

Đáng buồn là điều này sẽ không hoạt động vì tôi không có quyền kiểm soát máy tính nơi tập lệnh này sẽ được chạy. Tôi cần để có thể cung cấp cho họ mycode.vbs và biết rằng tuy nhiên họ cố gắng để chạy nó, nó sẽ luôn luôn được chạy với cscript chứ không phải là wscript. – Richard

3

Dưới đây là một tương tự trong JScript để làm .js file chạy trong cscript:

(function(ws) { 
    if (ws.fullName.slice(-12).toLowerCase() !== '\\cscript.exe') { 
    var cmd = 'cscript.exe //nologo "' + ws.scriptFullName + '"'; 
    var args = ws.arguments; 
    for (var i = 0, len = args.length; i < len; i++) { 
     var arg = args(i); 
     cmd += ' ' + (~arg.indexOf(' ') ? '"' + arg + '"' : arg); 
    } 
    new ActiveXObject('WScript.Shell').run(cmd); 
    ws.quit(); 
    } 
})(WScript); 

WScript.echo('We are now in CScript. Press Enter to Quit...'); 
WScript.stdIn.readLine(); 

https://gist.github.com/4482361

3

Hai bổ sung nhỏ để forceCScriptExecution cho tôi xem sổ của nó sau khi chấm dứt và xử lý mã trở lại của mình.

Sub forceCScriptExecution 
    Dim Arg, Str 
    If Not LCase(Right(WScript.FullName, 12)) = "\cscript.exe" Then 
     For Each Arg In WScript.Arguments 
      If InStr(Arg, " ") Then Arg = """" & Arg & """" 
      Str = Str & " " & Arg 
     Next 
     **ret =** CreateObject("WScript.Shell").Run **("cmd /k** cscript //nologo """ & WScript.ScriptFullName & """ " & Str**,1,true)** 
     WScript.Quit **ret** 
    End If 
End Sub 

Lưu ý: "cmd/k" để cửa sổ ở lại sau khi thực thi. Tham số "1" kích hoạt cửa sổ. Tham số "true" chờ kết thúc, do đó biến "ret" có thể trả lại mã lỗi.

0

Đây là đoạn mã tôi sử dụng cho một số tập lệnh của mình. Nó xử lý các đối số cũng như.Tất cả bạn phải làm là thay thế {EnterWorC} với hoặc là một "w" hoặc "c" VỚI dấu ngoặc kép

Dim WorC, Command, Arguments, I 

WorC={EnterWOrC} 'Make sure you replace "{EnterWOrC}" with a "w" or a "c" and BE SURE TO PUT QUOTES AROUND THE LETTER. 

WorC=LCase (WorC) 
If lcase (WorC)="w" Or lcase (WorC)="c" Then 

If LCase (Right (WScript.FullName,11))<> WorC & "script.exe" Then 
    command=WScript.ScriptFullName 
    Arguments="" 
    For I=0 To UBound (WScript.Arguments) 
     Arguments=Arguments & Chr (34) & WScript.Arguments(I) & Chr (34) & Space (1) 
    Next 
    CreateObject("Wscript.Shell").Run WorC & "script.exe " & Chr (34) & command & Chr (34) & Space (1) & Arguments, 1 
    WScript.Quit 
End If 
    WorC=Empty 
    Command=Empty 
    I=Empty 
    Arguments=Empty 
End If 

Ở đây bạn sẽ phải thay thế dòng thứ 2 (dòng KHÔNG trống thứ 2)

WorC={EnterWOrC} 'Make sure you replace "{EnterWOrC}" with a "w" or a "c" and BE SURE TO PUT QUOTES AROUND THE LETTER. 

Đối Wscript: WorC="W"

Đối cscript: WorC="C"

Đó là không phân biệt chữ hoa.

Các vấn đề liên quan