2

In a batch file I can get the width of the console window using one of the examples here:

Windows console width in environment variable

@echo off
for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do set CONSOLE_WIDTH=%%W
echo Console is %CONSOLE_WIDTH% characters wide

Similarly, I would like to know how to get the width of the parent shell's console when I run a VBscript from a Command Prompt. If I try running the above batch file from VBscript using:

CreateObject("WScript.Shell").Run "cmd /k FindWidth.bat"

A new console opens, and the width given by FindWidth.bat is for the new console window, not the console of the parent shell.

Using VBscript I can find the process ID of the parent shell using the following method: In a vbscript, how can i get the process id of the cmd.exe in which the vb script is running. Is there a way to do something similar to find its console column width? Maybe another method can be used since the process ID is known?

EDIT UPDATES:

I thank everyone for the comments. I'll try to add some more information of what I'm trying to accomplish. I have a kind of work around already but I was hoping for a slightly better solution.

The VBscript is run from a Command Prompt directly. Unfortunately, the VBscript is most likely run from wscript.exe because that is the default on normal Windows installations. But I still want to output error messages and other messages to the console and not to a popup window.

If I could guarantee it was run with cscript, there would be no problems. Restarting the VBscript with cscript starts a new process so any messages from the newly run csript VBscript go to a new console and not the original console.

I have a solution which works but it is clumsy because it uses a batch file wrapper with the same name as the .vbs but with a .bat extension instead of .vbs extension. All the batch script does is run the VBscript using cscript. It is mentioned in this topic: In vbscript, how do I run a batch file or command, with the environment of the current cmd prompt window? I was hoping to find a way to get rid of the batch file wrapper but now I don't think it is possible.

I was trying another workaround which allows WScript to be used. Since the process ID of the console window can be obtained, a message can be sent to the original console window by first guaranteeing it is activated with:

objShell.AppActivate(ProcessID)

Then the script can immediately send a message to the original console with:

objShell.SendKeys ":: " & WindowMessage & "{enter}"

The trick is using "::" to make the message a comment that doesn't do anything. This works okay. One small problem is that it makes the console window use the comment for the last command buffer so if the user presses the up arrow or F3 etc, the comment is shown like it was a command they typed themselves. That is annoying but since it is just a comment, no errors are produced and it isn't much of a problem.

The part that is annoying is that the message appears on the same line as a normal command and doesn't look like a proper cscript sent message. The reason I wanted the width of the console is to format the message by buffering it with the proper number of spaces so that it looks identical to a message that would have been sent from cscript. Then it would look like real stdout output except for the ":: " at the start of the message.

The script could just read the default setting for the command prompt but that will not format it correctly in a lot of cases.

If I could find a way to go to a new line with SendKeys and send the message before the PROMPT appears, that would do the same thing. Is there a character that could be sent which would start a new line before the PROMPT appears??

Is there a way of using VBscript to inject a text message into the stdout of a specific console window. Being that the process ID is known of the console that should get the stdout, is it possible for the wscript VBscript to run another batch script or another program silently which could use the Process ID to inject a message into the stdout of the original console window.

Ultimately, all I wanted was to have the VBscript file be run directly in a Command Prompt that can output messages to that same console. But to do that properly seems to require the user type "cscript scriptname.vbs arguments" instead of just "scriptname arguments" which is how it should be possible but apparently isn't! Using a batch file wrapper is another option that kind of tricks the user into running a different batch file instead of the VBscript file directly. I guess I would need to redo the script in a real computer language instead of a scripting language to make it work properly. I really don't understand why this is so difficult to accomplish with VBscript when it seems like it should be trivial.

It is a bit annoying that Windows sets VBscript to use WScript by default when WScript doesn't allow any console output at all. But CSCript can do both Windows popups and console output. Why even have WScript vs CScript distinction at all when it seems like everything can be done with CScript alone?

orbidia
  • 39
  • 3
  • I'm no VBScript expert, but I don't think you can call native functions such as `AttachConsole` to have the wscript.exe process attach to the console of its parent shell. In that case I think your only option is to manually run the script using cscript.exe, which should inherit the console. – Eryk Sun Jul 30 '17 at 10:49
  • 1
    There is no "parent shell". The VBScript host (`cscript.exe`) is a separate process, so there is a parent process, which might (or might not!) be be `cmd.exe`, but you don't have that kind of access to it anyway. I'm curious if someone comes up with a creative solution to this, but until then - what are you *actually* trying to do? – Tomalak Jul 30 '17 at 11:34
  • @Tomalak, for whatever reason the OP needs the column width of the console of the parent process, which for this use case is a shell -- probably CMD with the VBscript run from a batch script. Certainly the parent of the script doesn't have to be a shell or have a console. But the crux of the question in general is how to obtain information about the parent's console if it has one. The default VBScript host *is not* cscript.exe, but rather wscript.exe, which is the main problem. wscript.exe isn't a console application, and I don't think VBScript has a way to attach to an exiting console. – Eryk Sun Jul 30 '17 at 12:51
  • 2
    So, *if* the parent process is a `cmd.exe`, probably a batch script even, then the OP can set an environment variable there by the method they found themselves. The environment is inherited so the `cscript.exe` child process can see it (via `WSHShell.ExpandEnvironmentVariables()`. – Tomalak Jul 30 '17 at 13:00
  • @Tomalak, again, to clarify, it is not a cscript.exe process by default. If it were it could simply run mode.com itself because it would inherit the parent's console. But for wscript.exe the environment variable solution is good, assuming the OP controls what the parent process does. – Eryk Sun Jul 30 '17 at 13:10
  • Which brings us back to my original question. What is he *actually* trying to do? It's a waste of time to speculate. – Tomalak Jul 30 '17 at 13:16
  • I've updated the question with a lot more information. – orbidia Jul 30 '17 at 20:32
  • Text sent directly to the console window is handled by its message loop, which queues it as keyboard input records in its input buffer. The foreground console process can read input records from its stdin, or via "CONIN$" opened for reading, either as individual records or as a text stream. There's no way for you to simply write text on the console window without being attached to it. If you're attached to the console, you can write to its screen buffer by opening "CONOUT$" for writing. – Eryk Sun Jul 31 '17 at 04:50
  • @erkysun, so if the VBscript file is launched from the console window, is it attached in any way to the console window? Launching a batch script from the console window seems to allow output into the console window. Why doesn't the VBscript interpreter know it is attached to a console window and automatically allow output? I don't understand why VBscript has this limitation or distinction between WScript and CScript. Is the only reason because it is a sub-standard scripting language? – orbidia Jul 31 '17 at 18:38

0 Answers0