I have a little problem with the SetParent API. On my local system, it works fine. But when I put the program on a virtual machine, the handle does not work properly.

Here's what I've got in my code:

var si = new ProcessStartInfo(filetoexec, args);
si.UseShellExecute = true;
si.WindowStyle = ProcessWindowStyle.Normal;
var pr = new Process();
pr.StartInfo = si;
pr.StartInfo.CreateNoWindow = true;
pr.StartInfo = si;
pr.StartInfo.FileName = filetoexec;
pr.StartInfo.Arguments = args;
pr.EnableRaisingEvents = true;
pr.Exited += ProcessExited;
pr.Start();
pr.WaitForInputIdle(1000);
IntPtr rValue = SetParent(pr.Handle, formHandle); //rValue = Handle Verification

After this, I write out a log file which returns my parent handle, the process handle and my handle verification which is the rValue. Not sure if this has anything to do with it, but these processes that I am calling have been written in Cobol. Anyway, on my local machine I get something like the following: Parent Handle: 723138, Cobol Handle: 1700, Handle Verification: 460364 and so on with all the processes that I open. On the virtual machine on the other hand, the parent handle and cobol handles are fine. But the Handle Verification always returns 0. Would anybody know why that would be? Am I missing something in my code?

Edit:
formHandle = parent handle

Edited 1 Year Ago by lithium112

Maybe this article can help to understand the differences between process (or application) virtual machine, system virtual machine and host virtual machine.

Probably in your local machine the cobol process runs in the same process/host virtual machine than the form while in your system virtual machine is running in distinct process/host virtual machines just because the virtualization. This can be the reason to fail to set the parnet handle.

There are various cobol languange builders/versions but most of them are using a proces virtual machine to interact whith the OS.

Hope this helps.

I was finally able to find the answer. Here's my code:

pr.Start();
                        Process p = Process.GetProcessById(pr.Id);
                        Stopwatch sw = new Stopwatch();
                        while (p.MainWindowHandle == (IntPtr)0) {
                            p.Refresh();
                            sw.Start();
                            if (sw.ElapsedMilliseconds > 2000 || p.MainWindowHandle != (IntPtr)0) {
                                sw.Stop();
                                break;
                            }
                        }
                        IntPtr handle = p.MainWindowHandle;
                        pr.WaitForInputIdle(1000);
                        var rValue = SetParent(handle, formHandle);

                        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
This question has already been answered. Start a new discussion instead.