[vbox-dev] COM API ProcessCreate and GuestProcess.Write
LeeEll
info at cando.se
Mon Apr 8 21:01:20 GMT 2013
Hi Everybody!
I am working on a C# (.net 4.0) app that manages VirtualBox (version 4.2.1
r84104) on a number of slave machines. The slave machines run Win 7 64-bit
and the guest OS is win XP 32-bit. I am using the COM API to manage VB on
the slave machines.
My manager app now needs to be able to execute a program on the guest OS,
provide command parameters to it and to give it input via stdin and to get
output from stdout. The first use of this would be to open a command
window on the guest, execute command “ipconfig” and get the current IP
addresses from the command window output. But I can’t get it to work.
I get an exception when I try to write the ipconfig command to stdin. See
code below. As an alternative to writing to the process I have tried to
give the ipconfig command in the arguments for ProcessCreate, but that
doesn’t work either. The command window is opened in the guest OS, but it
just shows a blank window with a blinking caret, no path or any of the
other stuff that is normally shown in a new command window. If I click in
the command window and try to write something, nothing happens. I don’t
know if this is an indication of a problem or not. I guess it might be
that VB has captured stdin/stdout?
If I change the code so the command is “c:\windows\notepad.exe“, I get a
fully functioning notepad window in the guest OS. So the code for
executing a file on the guest seems to work. I haven’t tried to use
guestProcess.Write on anything other than the cmd.exe window.
Can someone please show me how I can use C# and the COM API to execute a
program (including cmd.exe) on the guest OS and then provide input to it
and get output from it?
Thanks!
My code looks like this (simplified for this post):
public MyReturnData GetVmIpAddresses(string vmName, string
userName, string password) {
var mrd = new MyReturnData();
IVirtualBox vbox;
IMachine machine = null;
Session session;
IGuestSession guestSession = null;
try {
// Init VirtualBoxCom
vbox = new VirtualBox.VirtualBox();
// Get machine
foreach (IMachine m in vbox.Machines) {
if (m.Name == vmName) {
machine = m;
break;
}
}
if (machine == null) {
// Return error. Code omitted for brevity
return mrd;
}
// Get GuestSession
session = new Session(); // (Virtualbox running on x64 OS
requires that this prog is also running as x64!)
machine.LockMachine(session, LockType.LockType_Shared);
guestSession = session.Console.Guest.CreateSession
(userName, password, "", "");
// Setup for Command Execution
var cmdArgs = new string[] { }; // Empty arguments array
var envVars = new string[] { }; // Empty environment vars
var flags = new ProcessCreateFlag[] { // I have tried
all these flags in different combinations
//ProcessCreateFlag.ProcessCreateFlag_WaitForProcessSta
rtOnly,
//ProcessCreateFlag.ProcessCreateFlag_WaitForStdOut,
//ProcessCreateFlag.ProcessCreateFlag_IgnoreOrphanedPro
cesses,
ProcessCreateFlag.ProcessCreateFlag_None,
};
// Open a command window on the VM
var guestProcess = guestSession.ProcessCreate
(@"c:\windows\system32\cmd.exe", cmdArgs, envVars, flags, 500);
if (guestProcess == null) {
// Return error. Code omitted for brevity
return mrd;
}
// Wait up to 1 second for process to start
var waitCount = 0;
if (guestProcess.Status !=
ProcessStatus.ProcessStatus_Error) {
while (waitCount <= 40 && guestProcess.Status !=
ProcessStatus.ProcessStatus_Started && guestProcess.Status !=
ProcessStatus.ProcessStatus_Error) {
Debug.WriteLine("Waiting... ({0})", waitCount);
waitCount++;
Thread.Sleep(25);
}
}
// Timeout or process error?
if (waitCount > 40 || guestProcess.Status !=
ProcessStatus.ProcessStatus_Started) {
// Return error. Code omitted for brevity
}
// Prepare command
var inputArray = Encoding.Default.GetBytes("ipconfig");
// Write ipconfig command to the command window
var written = guestProcess.Write(0, Convert.ToUInt32
(ProcessInputFlag.ProcessInputFlag_None), inputArray, 500);
// Exceptionon on line above: Writing to
process "c:\windows\system32\cmd.exe" (PID 3276) failed: VERR_TIMEOUT
// Wait a while for ipconfig to generate its output
Thread.Sleep(100);
// Read ipconfig output from cmd.exe process
var output = guestProcess.Read(1, 2000, 100); // Don't
know yet if this works
// Parse output for ip addresses and save in mrd
// TBD ?????
// Terminate process, close command window and sessions,
cleanup
// TBD ???????
}
catch (Exception ex) {
// Return error. Code omitted for brevity
}
// Return data in mrd
return mrd;
} // GetVmIpAddresses
More information about the vbox-dev
mailing list