简体   繁体   中英

Setting up ProcessStartInfo for C# process from CreateProcessAsUser with CREATE_SUSPENDED flag and JobObject

In my C# program, I need to (1) create a process in a suspended state and (2) modify the token. I am doing this so that I can register it to a JobObject so that if the parent process dies unexpectedly while the child is still running, the child is killed. I need to modify the token per business requirements.

I figured out that it is not possible to add an un-started C# Process to a JobObject , or create a Process in a suspended state, or modify its token. So, I am using C++ CreateProcessAsUser to accomplish these things. So far, so good:

      [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
      private static extern bool CreateProcessAsUser(
        IntPtr hToken,
        String lpApplicationName,
        String lpCommandLine,
        IntPtr lpProcessAttributes,
        IntPtr lpThreadAttributes,
        bool bInheritHandle,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        String lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);

      public static uint CreateSuspendedProcess(string appPath, string cmdLine = null, bool visible = false)
            result = CreateProcessAsUser(
              hUserToken, // Modified token - working great
              appPath, // Application Name - doesn't end up in Process.ProcessStartInfo?
              cmdLine, // is null
              IntPtr.Zero,
              IntPtr.Zero,
              false,
              dwCreationFlags, // contains CREATE_SUSPENDED
              pEnv,
              null, // working directory
              ref startInfo, // not related to C# ProcessStartInfo?
              out procInfo);

// does other stuff, and then returns the Process ID

Where I'm having a problem is actually starting the process.

From the caller (see snippet below), I attempt to get the process from the ID of the process I created with CreateProcessAsUser. The process made by CreateProcessAsUser doesn't have StartInfo containing the filename. I expected appPath to function the same as StartInfo.FileName, but there is something I do not understand here because process.StartInfo seems to be dummy info, per the documentation I read here that says GetProcesses, etc., will not return StartInfo and StartInfo cannot be modified once a process has started. I suppose creating a process in a suspended state counts as starting.

I'm a rookie developer, and have never used C++ before attempting to muddle through this, but what I have been able to learn is that maybe I shouldn't be trying to do Process.Start - but I haven't found any alternatives that satisfy the need to register the process to a JobObject .

 var processId = CreateSuspendedProcess(startInfo.FileName, startInfo.Arguments);

 IntPtr hProcess = IntPtr.Zero;

 using (var job = new Job())
 using (var process = Process.GetProcessById((int)processId)) // use the suspended process
 {

    var jobSuccess = job.AddProcess(process.Id); // this works

    if (!jobSuccess)
    {
       // do not proceed if process cannot be run in job object; dispose of both
       throw new Exception("Failed to add process to job object.");
    }

    // === I want the start info to have the filename, but can't except in Debug
    //process.StartInfo.FileName = startInfo.FileName;

    // other code here
    Process.Start(); // Get a no FileName error

Yep, the answer is to avoid using the C# Process class methods, and instead manually open and resume all threads in the process.

  [DllImport("kernel32.dll")]
  static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);

  [DllImport("kernel32.dll")]
  static extern int ResumeThread(IntPtr hThread);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM