How to reuse console used by current process - winapi

I want the following assembly to write Hello World! in the current console. Currently it is working but writes Hello World! into a new console window. I have tried removing the invoke AllocConsole statement but it does not write anything and exits with code -1073741819. What is the simplest way to use the existing console window when the executable is called from the terminal?
include 'win64ax.inc'
.data
tex TCHAR 'Hello World!'
dummy rd 1
.code
start:
; Don't want to allocate new console. How to use existing??
invoke AllocConsole
invoke WriteConsole, <invoke GetStdHandle, STD_OUTPUT_HANDLE>, tex, 12, dummy, 0
invoke Sleep, 1000
.end start

Related

Setting process exit code from GUI application [duplicate]

I can't get ExitCode to work for a VCL forms application. Here is my test application. It was created from the File / New menu in the Delphi 2007 IDE. The only change is that I added the line ExitCode := 42; at the end.
program Test;
uses
Forms,
Unit27 in 'Unit27.pas' {Form27};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm27, Form27);
Application.Run;
ExitCode := 42;
end.
Now, when I run it from the command line, %ERRORLEVEL% doesn't get set:
>.\Test.exe
>echo %ERRORLEVEL%
0
I was expected the value in %ERRORLEVEL% to be 42, but it isn't being updated.
I tried the same experiment in a console application, and that worked fine. Why isn't it working for my GUI application?
Your method of setting the exit code is fine. It's your test that's faulty.
The shell doesn't wait for GUI applications to finish running before prompting for the next command. Thus, the error level has already been established. You're checking the value at the time the command prompt was displayed, not at the time you ran the echo command.
Running programs in a batch file or command script modifies the behavior of the command interpreter to make it wait for each command to finish before running the next one, even for programs marked as using the GUI subsystem instead of the console subsystem. That's why the error level is reported correctly from batch files — the process you ran had finished before the command interpreter fetches the exit code. Without using a command script, you can try starting your program with the start command and passing it the /wait option. I'm not sure it forwards the exit code of the process it starts, though.
You can establish the exit code like you're doing, but on the console you have to test the %errorlevel% variable in the same batch to get the value.
Instead of running your commands in the command prompt, create a simple bat like this:
REM calltest.bat
.\Test.exe
echo %ERRORLEVEL%
and then, invoke your test:
>calltest
I got this in my test:
>calltest.bat
>project3.exe
>echo 47
For both, setting directly the ExitCode variable or calling Halt.
My OS is Win7 64, if it makes any difference. Printing the %errorlevel% directly from the command line prints 0.

How to start IDL

I manage to get this command in my MacBook Pro Terminal Window :
IDL>
I am now in Text Wrangler. I type in print, "Hello World "
How do I get the words "Hello World" to appear in my MacBook Pro Terminal Window, from TextWrangler ? Do I have to save the file first ? What extension should I save it with ? Where would I save it ?
Thanks,
Tze
Easiest method:
Save your file as "hello_world.pro".
Start IDL from the same directory as the "hello_world.pro" file or do:
IDL> cd, 'directory/hello/world/is/in'
At the IDL prompt:
IDL> hello_world
Hello World
Eventually you will want to learn about !path, which will allow IDL to find your routines even if you are not in the same directory as the file.
You could have this in a script hello.pro
a='Hello'
b='World'
print,a
print,b
end
Then call:
IDL> .r hello
And it will print:
Hello
World
and a and b will still be active variables on the command line. .run scripts are very useful for starting programs.

Pasue Console Application At End

I want to know how it is possible to pause a console application at end and by pressing enter, it ends in assembely. here is a peice of code which shows "hello world" on screen, but it will close immediatly. So how to pause program at end?
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
.data
sConsoleTitle db "Console Application",0
sWriteText db "Hello World",0
.code
Main PROC
LOCAL hStdout :DWORD
invoke SetConsoleTitleA, offset sConsoleTitle
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hStdout,EAX
invoke WriteConsoleA, hStdout, offset sWriteText, 16d, 0, 0
invoke ExitProcess, 0
Main ENDP
end Main
Since you're already working with a console (I see stdout and WriteConsole) I'm going to suggest that you work with a proper console:
cmd.exe. Can simply be run off Start -> Run and is included with every modern Windows. Can be modified to use different fonts, resized, etc.
Windows PowerShell. Most people like it. I don't.
A terminal program like Console. Tabs, translucency and Linux-like mouse behavior are great to have.
Clicking an .exe to run it is great, but what happens if you want to supply it input? Command line parameters? What if you want to redirect stdin/stdout? What if you want to pipe a file to it, or it to another program, like grep? What if you wanted to run your program non-interactively, e.g. from a script?
It's one of Windows's shortcomings to be unable to work with console programs easily. Please do not compensate for this in your code and upset everyone who's found a way to do it.
Another option is creating a batch file that calls your executable and then does pause.

How do I get the exit code via %errorlevel% , its not working anymore with assembly program

I want to get the exit code of my tutorial assembly program (using masm32 and link). It was working fine, I would type echo %errorlevel% and it would display my exit code that I typed in after invoke ExitProcess. Now it doesn't work anymore. I'm using VirtualBox on an OpenSuse 12.1 host and Windows Vista Home Premium as the guest. I've searched for answers but have come up short. Most complaints are about using a batch file, which is not what I'm trying to do. Here is the simple program
hello_world.asm
.586
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
HelloWorld db "Hello World!", 0
.code
start:
invoke MessageBox, NULL, addr HelloWorld, addr HelloWorld, MB_OK
invoke ExitProcess, 2
end start
I expect it to return 2, but echo %errorlevel% returns 0. Is there something I'm missing? Thanks, and I apologize this question has been answered to death. I just can't find my answer.
Edit: Actually, I found part of my answer. It only works if I link using /SUBSYSTEM:CONSOLE. Using /SUBSYSTEM:WINDOWS always returns 0. I don't know what to make of this. where is the exit code with a windows program? any info greatly appreciated.
If your subsystem is Windows, then the command processor returns to the command prompt immediately without waiting for the program to exit. (Try it with notepad for example.) Since time travel has not yet been invented, it cannot tell you what the exit code of the program is, since the program hasn't exited yet.
Launch the process like this:
start /wait helloworld
That will make the command shell wait until the process has finished, so that it can retrieve the exit code.
(You don't need to do this if you are using a batch file.)

directing output from executed process to current cmd

Can I execute a program from a JScript script in such a way that the out put of the executed program will be written to the current console?
Currently I am using Shell.Application.ShellExecute and it is opening another new console for the executed application.
The JScript in my case is a wrapper around a compiler which is executed with the ShellExecute. So what happens is that all the compiler errors are lost because they are printed in another console.
If all you are worried about is capturing your compiler output then you can redirect the output to a file (I suggest both stdout and stderr). Something like this:
var shell = new ActiveXObject("WScript.Shell");
shell.Exec('YourCommand 1>yourOutput.txt 2>&1 ')
If you really want to see the ouptut in your current console window (I don't blame you), then you can use this:
var shell = new ActiveXObject("WScript.Shell");
WScript.StdOut.Write( shell.Exec('YourCommand 2>&1').StdOut.ReadAll() );
Note - if your command has the potential for asking for input, then you must provide input via a pipe or redirection in the command string (or you could redirect input to nul). Otherwise the program will hang.

Resources