Salida de vbscript a la consola

Respuestas:

311

Quiere decir:

Wscript.Echo "Like this?"

Si ejecuta eso en wscript.exe(el controlador predeterminado para la extensión .vbs, lo que obtendrá si hace doble clic en el script) obtendrá un cuadro de diálogo "MessageBox" con su texto. Si ejecuta eso debajo cscript.exeobtendrá salida en la ventana de su consola.

Evan Anderson
fuente
1
Se puede utilizar directamente en la wscript.exe la función MsgBox("text")o MsgBox(object.property), pero Wscript.Echoes más fácil escribir. Gracias.
m3nda
22
Sin intuición para mí, se WScript.Echo debe usar para saber si está ejecutando a través de WScripto CScript. Es decir, no hay un CScript.Echo, en caso de que los futuros googlers se pregunten. ( Muy contento de que los msgboxes hayan desaparecido [cuando se ejecutan con cscript], sin embargo; gracias.)
ruffin
1
@GabrielStaples - No con el stock WScript.Echo. Supongo que si quisieras permanecer totalmente dentro de WScript, podrías hacer algo horriblemente dudoso como Ejecutar otro proceso para hacer un "SendKeys" al proceso padre para cerrar el MessageBox.
Evan Anderson
44
En realidad, acabo de encontrar este popupmétodo. Muy similar, echopero le permite especificar un tiempo de espera después del cual se cerrará automáticamente el cuadro emergente. Muy conveniente y fácil de usar: technet.microsoft.com/en-us/library/ee156593.aspx
Gabriel Staples
63

Esto se encontró en Dragon-IT Scripts y Code Repository .

Puede hacer esto con lo siguiente y mantenerse alejado de las diferencias cscript / wscript y le permite obtener la misma salida de consola que tendría un archivo por lotes. Esto puede ayudar si llama a VBS desde un archivo por lotes y necesita hacer que se vea perfecto.

Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set stderr = fso.GetStandardStream (2)
stdout.WriteLine "This will go to standard output."
stderr.WriteLine "This will go to error output."
RLH
fuente
55
Si el script se inicia haciendo doble clic y, por lo tanto, se abre con wscript, el script genera un mensaje de error: "Identificador no válido".
Bernhard Hiller
66
@Bernhard: Recibirá este error si ejecuta el script usando wscript.exe. Wscript está orientado a Windows y no tiene secuencias de consola. Utilice cscript.exe en su lugar: technet.microsoft.com/en-us/library/bb490816.aspx
Axel Kemper
20
@BernhardHiller tiene un punto válido. El objetivo de esta respuesta es que usar stdout directamente evitaría las diferencias CScript / WScript. Eso es incorrecto. Esta solución solo funciona bajo CScript.exe, por lo que no parece haber muchos beneficios con solo usarla WScript.Echo. De hecho, la diferencia se amplía porque el script ya no se ejecutará en absoluto con WScript. Es una técnica válida que tiene sus usos, por ejemplo, si uno necesita escribir en StdErr, pero en el contexto de esta respuesta, es engañoso.
Tim Long
3
Solo quiero aclarar el beneficio de este método WScript.Echo: se cscript //b foobar.vbs ejecuta foobar.vbssin ninguna salida de consola, pero por el método de Rob puede tener salida incluso cuando se pasa \\bacscript.exe
S. Razi
24

Solo necesita forzar cscript en lugar de wscript. Siempre uso esta plantilla. La función ForceConsole () ejecutará sus vbs en cscript, también tiene un buen alias para imprimir y escanear texto.

 Set oWSH = CreateObject("WScript.Shell")
 vbsInterpreter = "cscript.exe"

 Call ForceConsole()

 Function printf(txt)
    WScript.StdOut.WriteLine txt
 End Function

 Function printl(txt)
    WScript.StdOut.Write txt
 End Function

 Function scanf()
    scanf = LCase(WScript.StdIn.ReadLine)
 End Function

 Function wait(n)
    WScript.Sleep Int(n * 1000)
 End Function

 Function ForceConsole()
    If InStr(LCase(WScript.FullName), vbsInterpreter) = 0 Then
        oWSH.Run vbsInterpreter & " //NoLogo " & Chr(34) & WScript.ScriptFullName & Chr(34)
        WScript.Quit
    End If
 End Function

 Function cls()
    For i = 1 To 50
        printf ""
    Next
 End Function

 printf " _____ _ _           _____         _    _____         _     _   "
 printf "|  _  |_| |_ ___ ___|     |_ _ _ _| |  |   __|___ ___|_|___| |_ "
 printf "|     | | '_| . |   |   --| | | | . |  |__   |  _|  _| | . |  _|"
 printf "|__|__|_|_,_|___|_|_|_____|_____|___|  |_____|___|_| |_|  _|_|  "
 printf "                                                       |_|     v1.0"
 printl " Enter your name:"
 MyVar = scanf
 cls
 printf "Your name is: " & MyVar
 wait(5)
MadAntrax
fuente
¿Estás seguro de que responde la pregunta real ?
dakab
Sí, solo llame a ForceConsole () y luego use printf () para imprimir texto en la consola de salida. También tiene otro alias para borrar la pantalla, escanear texto y esperar (dormir)
MadAntrax
1
La mejor solución de la historia, gracias, pero solo importa la función "ForceConsole", "printf" y el resto son totalmente innecesarios, ya que si obliga a cerrar el script actual en la instancia de Wscript.exe y luego ejecuta una nueva instancia de cscript.exe de el script actual, entonces Wscript.Echo es la salida a esa instancia de la consola ...
ElektroStudios
6

Encontré esta publicación y volví a un enfoque que usé hace algún tiempo, que es similar al de @ MadAntrax.

La principal diferencia es que utiliza una clase VBScript definida por el usuario para envolver toda la lógica para cambiar a CScript y enviar texto a la consola, por lo que hace que el script principal sea un poco más limpio.

Esto supone que su objetivo es transmitir la salida a la consola, en lugar de que la salida vaya a los cuadros de mensajes.

La clase cCONSOLE está abajo. Para usarlo, incluya la clase completa al final de su secuencia de comandos y luego ejemplifíquela justo al comienzo de la secuencia de comandos. Aquí hay un ejemplo:

    Option Explicit

'// Instantiate the console object, this automatically switches to CSCript if required
Dim CONS: Set CONS = New cCONSOLE

'// Now we can use the Consol object to write to and read from the console
With CONS

    '// Simply write a line
     .print "CSCRIPT Console demo script"

     '// Arguments are passed through correctly, if present
     .Print "Arg count=" & wscript.arguments.count

     '// List all the arguments on the console log
     dim ix
     for ix = 0 to wscript.arguments.count -1
        .print "Arg(" & ix & ")=" & wscript.arguments(ix)
     next

     '// Prompt for some text from the user
     dim sMsg : sMsg = .prompt( "Enter any text:" )

     '// Write out the text in a box
     .Box sMsg

     '// Pause with the message "Hit enter to continue"
     .Pause

End With     




'= =========== End of script - the cCONSOLE class code follows here

Aquí está el código para la clase cCONSOLE

     CLASS cCONSOLE
 '= =================================================================
 '= 
 '=    This class provides automatic switch to CScript and has methods
 '=    to write to and read from the CSCript console. It transparently
 '=    switches to CScript if the script has been started in WScript.
 '=
 '= =================================================================

    Private oOUT
    Private oIN


    Private Sub Class_Initialize()
    '= Run on creation of the cCONSOLE object, checks for cScript operation


        '= Check to make sure we are running under CScript, if not restart
        '= then run using CScript and terminate this instance.
        dim oShell
        set oShell = CreateObject("WScript.Shell")

        If InStr( LCase( WScript.FullName ), "cscript.exe" ) = 0 Then
            '= Not running under CSCRIPT

            '= Get the arguments on the command line and build an argument list
            dim ArgList, IX
            ArgList = ""

            For IX = 0 to wscript.arguments.count - 1
                '= Add the argument to the list, enclosing it in quotes
                argList = argList & " """ & wscript.arguments.item(IX) & """"
            next

            '= Now restart with CScript and terminate this instance
            oShell.Run "cscript.exe //NoLogo """ & WScript.ScriptName & """ " & arglist
            WScript.Quit

        End If

        '= Running under CScript so OK to continue
        set oShell = Nothing

        '= Save references to stdout and stdin for use with Print, Read and Prompt
        set oOUT = WScript.StdOut
        set oIN = WScript.StdIn

        '= Print out the startup box 
            StartBox
            BoxLine Wscript.ScriptName
            BoxLine "Started at " & Now()
            EndBox


    End Sub

    '= Utility methods for writing a box to the console with text in it

            Public Sub StartBox()

                Print "  " & String(73, "_") 
                Print " |" & Space(73) & "|"
            End Sub

            Public Sub BoxLine(sText)

                Print Left(" |" & Centre( sText, 74) , 75) & "|"
            End Sub

            Public Sub EndBox()
                Print " |" & String(73, "_") & "|"
                Print ""
            End Sub

            Public Sub Box(sMsg)
                StartBox
                BoxLine sMsg
                EndBox
            End Sub

    '= END OF Box utility methods


            '= Utility to center given text padded out to a certain width of text
            '= assuming font is monospaced
            Public Function Centre(sText, nWidth)
                dim iLen
                iLen = len(sText)

                '= Check for overflow
                if ilen > nwidth then Centre = sText : exit Function

                '= Calculate padding either side
                iLen = ( nWidth - iLen ) / 2

                '= Generate text with padding
                Centre = left( space(iLen) & sText & space(ilen), nWidth )
            End Function



    '= Method to write a line of text to the console
    Public Sub Print( sText )

        oOUT.WriteLine sText
    End Sub

    '= Method to prompt user input from the console with a message
    Public Function Prompt( sText )
        oOUT.Write sText
        Prompt = Read()
    End Function

    '= Method to read input from the console with no prompting
    Public Function Read()
        Read = oIN.ReadLine
    End Function

    '= Method to provide wait for n seconds
    Public Sub Wait(nSeconds)
        WScript.Sleep  nSeconds * 1000 
    End Sub

    '= Method to pause for user to continue
    Public Sub Pause
        Prompt "Hit enter to continue..."
    End Sub


 END CLASS
JohnRC
fuente
3

Hay cinco formas de enviar texto a la consola:

Dim StdOut : Set StdOut = CreateObject("Scripting.FileSystemObject").GetStandardStream(1)

WScript.Echo "Hello"
WScript.StdOut.Write "Hello"
WScript.StdOut.WriteLine "Hello"
Stdout.WriteLine "Hello"
Stdout.Write "Hello"

WScript.Echo saldrá a la consola, pero solo si el script se inicia usando cscript.exe. Saldrá a los cuadros de mensaje si comenzó a usar wscript.exe.

WScript.StdOut.Write y WScript.StdOut.WriteLine siempre saldrán a la consola.

StdOut.Write y StdOut.WriteLine también siempre saldrán a la consola. Requiere la creación de objetos adicionales, pero es aproximadamente un 10% más rápido que WScript.Echo.

Regis Desrosiers
fuente
1
... y como se dijo en un comentario a respuestas anteriores, esto no funciona cuando se ejecuta con wscript.exe: stackoverflow.com/questions/4388879/…
maxxyme
También encontré una explicación sobre GetStandardStream () vs WScript.StdIn / .StdOut / .StdErr: "VBScript en una cáscara de nuez: una referencia rápida de escritorio (2ª edición)" books.google.fr/books?id=NLpuZSatG3QC página 298 dice que es " funcionalmente equivalente ".
maxxyme