IGuest.getProcessOutput returns nothing...?

Discussions about using Windows guests in VirtualBox.
Post Reply
Halo
Posts: 5
Joined: 2. Jun 2012, 23:53

IGuest.getProcessOutput returns nothing...?

Post by Halo »

Hi there,

I'm currently trying to start a process in my VM (Windows 7 x86) from the host system (Ubuntu x64) and read its stdout using the C++ VirtualBox API.
I managed the first part (starting the process), but the second (reading stdout) won't work for me.

The problem ist, that the method IGuest.getProcessOutput always returns an empty buffer and zero bytes read. Additionally, even the stdout in the guest system stays empty!
I double checked with starting a simple console programm which does nothing else then writing a single line of text to stdout every second.
When starting with:
- vboxmanage guestcontrol execute: stdout stays emtpy
- C++ API IGuest: stdout stays empty
- manually (directlly in the guest system): works as expected, writes to stdout, visible in console

My code (snippet):

Code: Select all

PRUint32 pid = <set prior>
// ### read process output
const PRUint32 processFlags = 0; // Should not be used! (according to documentation)
const PRUint32 timeoutMS = 0;
const PRInt64 readLength = 500; // bytes to read
PRUint32 actualSize;
PRUint8 * buffer;
nsresult rc = guest->GetProcessOutput(pid, processFlags, timeoutMS, readLength, &actualSize, &buffer);
After executing this, actualSize is always 0 while rc is always OK (0, too).

Can anyone provide some hints or insight on this? Much appreciated!! =)

VirtualBox Version: 4.1.16
mpack
Site Moderator
Posts: 39134
Joined: 4. Sep 2008, 17:09
Primary OS: MS Windows 10
VBox Version: VirtualBox+Oracle ExtPack
Guest OSses: Mostly XP

Re: IGuest.getProcessOutput returns nothing...?

Post by mpack »

Do you know for a fact that the guest app writes to stdout? In other words, it is a console app, right? Though I must admit that I don't know if "stdout" has any true existence in Windows (Windows != Unix).

Moving to "Windows Guests".
Halo
Posts: 5
Joined: 2. Jun 2012, 23:53

Re: IGuest.getProcessOutput returns nothing...?

Post by Halo »

Hey mpack,
thanks for your fast answer!

Yes, that's what I meant with "double checked". I used the following console app for testing:

Code: Select all

#include <windows.h>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char * argv) {
	string msg("haaaalllo...!");
	while (true) {
		cout << msg << endl;
		Sleep(1000);
	}
	return 0;
};
When running it under Windows, it behaves as expected and prints msg to the console window every second.
When started via IGuest.executeProcess even the console window on the guest stays empty! (and IGuest.getProcessOutput returns nothing) :o

Really don't know, but what else could "process output" mean?
Are there any flags I forgot to set, or environment variables I need to set for the "executeProcess"-command beforehand?
mpack
Site Moderator
Posts: 39134
Joined: 4. Sep 2008, 17:09
Primary OS: MS Windows 10
VBox Version: VirtualBox+Oracle ExtPack
Guest OSses: Mostly XP

Re: IGuest.getProcessOutput returns nothing...?

Post by mpack »

I have no doubt that a console app in Windows looks (to the eye) similar to a command line app in Unix. However the underlying architecture is completely different. I'm not sure that Windows even has a system wide character based pipe called "stdout" whose output you could tap. I may be totally wrong about that however, because it's just a feature I've never needed for my own code. I'm just questioning the assumption.

VirtualBox is a portable app: just because it supports a certain feature doesn't mean that the feature exists on every guest/host OS.
Halo
Posts: 5
Joined: 2. Jun 2012, 23:53

Re: IGuest.getProcessOutput returns nothing...?

Post by Halo »

Reading my own post again finally gave me the insight I was looking for:
One has to set the ExecuteProcessFlag::WaitForStdOut when calling IGuest.ExecuteProcess. Then IGuest.getProcessOutput returns the wanted stdout.

I found this by reading the SDK Reference PDF more carefully then the first time; however, the online doc of getProcessOuput (unable to post link here as newbie) doesn't mention it!!!

Thanks for your time mpack :)
useruser1
Posts: 7
Joined: 20. Jul 2012, 21:29

Re: IGuest.getProcessOutput returns nothing...?

Post by useruser1 »

I actually am trying to do something similar. Host is Windows 7 64 bit and Guest is Windows XP 32 bit. I am using VirtualBox Type Library version 1.3.0.0. I am trying to make a call to ExecuteProcess. I made a similar program which just outputs hello every second. When I make the call to ExecuteProcess to start this program in the VM, the console application opens up in the command window, but I do not see any output. When I run the program manually in the VM I get the output I expected.

My eventual goal is to get the std out using GetProcessOutput. To try this I made a call to this after the ExecuteProcess, when setting the ExecuteProcessFlag_WaitForStdOut, and I did not get any output returned either. So I figured I would try and see if I could at least get the ExecuteProcess working and see the output in the command window first. Here is my code.

Code: Select all

uint pid;
progress = sess.Console.Guest.ExecuteProcess(@"C:\Documents and Settings\cj\Desktop\StdOutTest.exe",
                                                                      (uint)ExecuteProcessFlag.ExecuteProccessFlag_None,
                                                                      null,
                                                                      null,
                                                                      "cj"
                                                                      "password"
                                                                       0,
                                                                       out pid};

To test GetProcessOutput I used....

uint pid;
progress = sess.Console.Guest.ExecuteProcess(@"C:\Documents and Settings\cj\Desktop\StdOutTest.exe",
                                                                      (uint)ExecuteProcessFlag.ExecuteProccessFlag_WaitForStdOut,
                                                                      null,
                                                                      null,
                                                                      "cj"
                                                                      "password"
                                                                       0,
                                                                       out pid);

Arrary output = sess.Console.Guest.GetProcessOutput(pid,
                                                                                0,
                                                                                0,
                                                                                10000);
                                           
Thanks!
Post Reply