ACR_DatabaseConnector.DatabaseConnector.CreateProcessInJob C# (CSharp) Метод

CreateProcessInJob() приватный статический Метод

Create a process and attach it to a job. The process is resumed by the time the call returns if the call was successful.
private static CreateProcessInJob ( string ExeFileName, string CommandLine, SafeWaitHandle Job, bool BreakawayOk = false ) : Process
ExeFileName string Supplies the fully qualified exe file /// name of the main process image.
CommandLine string Supplies command line arguments that do /// not include the implicit exe file name argument.
Job Microsoft.Win32.SafeHandles.SafeWaitHandle Supplies a job handle.
BreakawayOk bool Supplies true if job breakaway is to be /// considered acceptable.
Результат System.Diagnostics.Process
        private static Process CreateProcessInJob(string ExeFileName, string CommandLine, SafeWaitHandle Job, bool BreakawayOk = false)
        {
            PROCESS_INFORMATION ProcessInfo;
            STARTUPINFO StartupInfo;
            bool Succeeded = false;

            ProcessInfo.hProcess = IntPtr.Zero;
            ProcessInfo.hThread = IntPtr.Zero;

            StartupInfo.cb = 0;
            StartupInfo.lpReserved = null;
            StartupInfo.lpDesktop = null;
            StartupInfo.lpTitle = null;
            StartupInfo.dwX = 0;
            StartupInfo.dwY = 0;
            StartupInfo.dwXSize = 0;
            StartupInfo.dwYSize = 0;
            StartupInfo.dwXCountChars = 0;
            StartupInfo.dwYCountChars = 0;
            StartupInfo.dwFillAttribute = 0;
            StartupInfo.dwFlags = (UInt32)STARTFLAGS.UseShowWindow;
            StartupInfo.wShowWindow = (UInt16)SHOWCMD.SW_HIDE;
            StartupInfo.cbReserved2 = 0;
            StartupInfo.lpReserved2 = IntPtr.Zero;
            StartupInfo.hStdInput = IntPtr.Zero;
            StartupInfo.hStdOutput = IntPtr.Zero;
            StartupInfo.hStdError = IntPtr.Zero;

            StartupInfo.cb = Marshal.SizeOf(StartupInfo);

            try
            {
                string RealCommandLine = String.Format("\"{0}\" {1}", ExeFileName, CommandLine);
                bool BreakawayTried = false;

                //
                // Create the process.
                //

                for (; ; )
                {
                    if (CreateProcessA(ExeFileName,
                        CommandLine,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        0,
                        PROCESSCREATIONFLAGS.CreateSuspended | (BreakawayOk && !BreakawayTried ? PROCESSCREATIONFLAGS.CreateBreakawayFromJob : 0),
                        IntPtr.Zero,
                        null,
                        ref StartupInfo,
                        out ProcessInfo) == 0)
                    {
                        int LastError = Marshal.GetLastWin32Error();

                        ProcessInfo.hProcess = IntPtr.Zero;
                        ProcessInfo.hThread = IntPtr.Zero;

                        if ((LastError == ERROR_ACCESS_DENIED) && (BreakawayOk) && (!BreakawayTried))
                        {
                            Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to create process with breakaway due to ERROR_ACCESS_DENIED, trying again without breakaway.");
                            BreakawayTried = true;
                            continue;
                        }

                        throw new ApplicationException(String.Format("CreateProcessA(ExeFileName = '{0}', CommandLine = '{1}') failed: {2}",
                            ExeFileName,
                            CommandLine,
                            LastError));
                    }

                    break;
                }

                //
                // Join it to the job so that it will be cleaned up if the
                // nwn2server process exits unexpectedly.
                //

                if (AssignProcessToJobObject(Job.DangerousGetHandle(), ProcessInfo.hProcess) == 0)
                {
                    int LastError = Marshal.GetLastWin32Error();
                    bool ContinueAnyway = false;

                    if (LastError == ERROR_ACCESS_DENIED)
                    {
                        if (BreakawayOk == false)
                        {
                            Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to assign process to job due to ERROR_ACCESS_DENIED, trying with breakaway.");
                            return CreateProcessInJob(ExeFileName, CommandLine, Job, true);
                        }
                        else
                        {
                            Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to assign process to job due to ERROR_ACCESS_DENIED and breakaway failed, ignoring failure.");
                            ContinueAnyway = true;
                        }
                    }

                    if (!ContinueAnyway)
                        throw new ApplicationException("AssignProcessToJobObject failed: " + LastError);
                }

                //
                // Attach a Process object to the process by ID.   Since a
                // handle to the process is currently open, the process ID is
                // guaranteed to not be recycled in this interval.  The .NET
                // Process object will be used to wait on the process to exit
                // in the monitor thread.
                //

                Process ProcessObject = Process.GetProcessById((int)ProcessInfo.dwProcessId);

                //
                // Finally, resume the thread and call it done.
                //

                if (ResumeThread(ProcessInfo.hThread) == UInt32.MaxValue)
                    throw new ApplicationException("ResumeThread failed: " + Marshal.GetLastWin32Error());

                Succeeded = true;
                return ProcessObject;
            }
            finally
            {
                if (ProcessInfo.hProcess != IntPtr.Zero)
                {
                    if (!Succeeded)
                        TerminateProcess(ProcessInfo.hProcess, 0);

                    CloseHandle(ProcessInfo.hProcess);
                    ProcessInfo.hProcess = IntPtr.Zero;
                }

                if (ProcessInfo.hThread != IntPtr.Zero)
                {
                    CloseHandle(ProcessInfo.hThread);
                    ProcessInfo.hThread = IntPtr.Zero;
                }
            }
        }