如何将CreateProcessWithLogonW与扩展属性一起使用(STARTUPINFOEX)

时间:2015-01-24 20:47:06

标签: c# pinvoke io-redirection createprocessasuser

我真的希望能够通过共享管道进行文件重定向,并将继承句柄列表仅过滤到那些stdout / stderr / stdin句柄,并且据我所知,STARTUPINFOEX和扩展属性是可行的方法那。我还需要能够以不同的用户身份启动。

  • CreateProcess在执行STARTUPINFOEX时可以为我工作,并且不传递任何属性或单个属性(要么更改父项,要么过滤继承的句柄)。
  • CreateProcessWithLogonW在执行STARTUPINFOEX时有效,但前提是我从创建标志中取消EXTENDED_STARTUPINFO_PRESENT(基本上将STARTUPINFOEX视为STARTUPINFO,即使startupinfo.cb是完整结构)。
  • 如果我添加EXTENDED_STARTUPINFO_PRESENT,我会得到有用的"参数不正确",即使不使用任何属性(适用于CreateProcess)

以下内容有效,直到您取消注释// | NativeMethods.EXTENDED_STARTUPINFO_PRESENT,

    public static void CreateProcessExtended(
        string userName,
        SecureString password)
    {
        var startupInfoEx = new NativeMethods.STARTUPINFOEX { StartupInfo = new NativeMethods.STARTUPINFO() };
        startupInfoEx.StartupInfo.dwFlags = NativeMethods.STARTF_USESHOWWINDOW;
        startupInfoEx.StartupInfo.wShowWindow = 0; // SW_HIDE
        NativeMethods.PROCESS_INFORMATION processInfo;

        startupInfoEx.StartupInfo.cb = Marshal.SizeOf(startupInfoEx);
        IntPtr passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
        bool retVal = NativeMethods.CreateProcessWithLogonW(
            userName,
            null,
            passwordPtr,
            NativeMethods.LogonFlags.LOGON_WITH_PROFILE,
            null,
            @"C:\windows\system32\notepad.exe",
            (uint)NativeMethods.CREATE_NO_WINDOW | NativeMethods.CREATE_SUSPENDED,// | NativeMethods.EXTENDED_STARTUPINFO_PRESENT,
            IntPtr.Zero,
            null,
            ref startupInfoEx,
            out processInfo);
        if (!retVal)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFO
    {
        public Int32 cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public Int32 dwX;
        public Int32 dwY;
        public Int32 dwXSize;
        public Int32 dwYSize;
        public Int32 dwXCountChars;
        public Int32 dwYCountChars;
        public Int32 dwFillAttribute;
        public Int32 dwFlags;
        public Int16 wShowWindow;
        public Int16 cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFOEX
    {
        public STARTUPINFO StartupInfo;
        public IntPtr lpAttributeList;
    }

    [return: MarshalAs(UnmanagedType.Bool)]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
    public static extern bool CreateProcessWithLogonW(
        string userName,
        string domain,
        IntPtr password,
        LogonFlags logonFlags,
        string lpApplicationName,
        string lpCommandLine,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        [In] ref STARTUPINFOEX lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);

Edit.1 在过滤的句柄属性列表中发送,以防它是合同差异,需要扩展属性为IntPtr.Zero以外的其他属性。仍然失败了。再次,在CreateProcess中工作,使用这些新sig在CreateProcessWithLogonW中失败:

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UpdateProcThreadAttribute(
        IntPtr lpAttributeList, uint dwFlags, uint Attribute, IntPtr lpValue,
        IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool InitializeProcThreadAttributeList(
        IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);

0 个答案:

没有答案