예제 #1
0
        public static ProcessInTheJob CreateProcessInTheJob(
            string desktopName,
            string appPath,
            string cmdLine,
            IntPtr jobHandle)
        {
            var newJobHandle = IntPtr.Zero;

            if (jobHandle == IntPtr.Zero)
            {
                newJobHandle = jobHandle = WinApi.CreateJobObject(IntPtr.Zero, null);
                // TODO set limits etc
            }

            const uint NORMAL_PRIORITY_CLASS = 0x0020;
            const uint CREATE_SUSPENDED      = 0x00000004;

            var sInfo = new WinApi.STARTUPINFO();

            sInfo.cb        = Marshal.SizeOf(sInfo);
            sInfo.lpDesktop = desktopName;

            var pSec = new WinApi.SECURITY_ATTRIBUTES();
            var tSec = new WinApi.SECURITY_ATTRIBUTES();

            pSec.nLength = Marshal.SizeOf(pSec);
            tSec.nLength = Marshal.SizeOf(tSec);

            string commandLine = "";

            if (!string.IsNullOrEmpty(appPath) && !string.IsNullOrEmpty(cmdLine))
            {
                commandLine = $"{appPath} {cmdLine}";
            }
            else if (!string.IsNullOrEmpty(cmdLine))
            {
                commandLine = cmdLine;
            }

            var retValue = WinApi.CreateProcess(appPath, commandLine,
                                                ref pSec, ref tSec, false,
                                                NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED,
                                                IntPtr.Zero, null, ref sInfo, out var pInfo);

            WriteLine("Process ID (PID): " + pInfo.dwProcessId);
            WriteLine("Process Handle : " + pInfo.hProcess);

            var r = WinApi.AssignProcessToJobObject(jobHandle, pInfo.hProcess);

            if (!r)
            {
                if (newJobHandle != IntPtr.Zero)
                {
                    WinApi.CloseHandle(newJobHandle);
                }
                return(new ProcessInTheJob(ProcessInTheJob.Status.COULD_NOT_ASSIGN_JOB, IntPtr.Zero, pInfo));
            }

            // Ensure that killing one process kills the others
            var extendedInfo = new WinApi.JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation =
                {
                    LimitFlags = (short)WinApi.LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
                }
            };

            int    length          = Marshal.SizeOf(typeof(WinApi.JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!WinApi.SetInformationJobObject(jobHandle,
                                                WinApi.JOBOBJECTINFOCLASS.JobObjectExtendedLimitInformation,
                                                extendedInfoPtr, (uint)length))
            {
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
            }

            Marshal.FreeHGlobal(extendedInfoPtr);

            WinApi.ResumeThread(pInfo.hThread);
            return(new ProcessInTheJob(ProcessInTheJob.Status.JOB_ASSIGNED, jobHandle, pInfo));
        }
예제 #2
0
 public static void CloseDesktop(IntPtr handle)
 {
     WinApi.CloseDesktop(handle);
 }