【问题标题】:How to create process as user with arguments如何使用参数以用户身份创建进程
【发布时间】:2018-02-28 09:21:50
【问题描述】:

尝试使用portablechrome.exe 以用户身份创建进程,但我无法使用参数处理它。

如何打开带有参数的 HTML 文件? 如portablechrome.exe sample.html --kiosk

我正在使用这样的系统服务:

string url = @System.AppDomain.CurrentDomain.BaseDirectory + "updater.html ";
string kioskMode = url + " --kiosk --incognito --disable-pinch --overscroll-history-navigation=0 ";

StartProcessAsCurrentUser("C:\\Chrome\\PortableChrome.exe", kioskMode);

还有我的 StartProcessAsUser 包装器:

public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true)
{
    appPath = appPath + " " + cmdLine;
    var hUserToken = IntPtr.Zero;
    var startInfo = new STARTUPINFO();
    var procInfo = new PROCESS_INFORMATION();
    var pEnv = IntPtr.Zero;
    int iResultOfCreateProcessAsUser;

    startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));

    try
    {
        if (!GetSessionUserToken(ref hUserToken))
        {
            throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed.");
        }

        uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);
        startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE);
        startInfo.lpDesktop = "winsta0\\default";

        if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))
        {
            throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed.");
        }

        if (!CreateProcessAsUser(hUserToken,
            appPath, // Application Name
            cmdLine, // Command Line
            IntPtr.Zero,
            IntPtr.Zero,
            false,
            dwCreationFlags,
            pEnv,
            workDir, // Working directory
            ref startInfo,
            out procInfo))
        {
            iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
            throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed.  Error Code -" + iResultOfCreateProcessAsUser);
        }

调用此函数后,kiosk 模式 Incognito Chrome 会打开,但不会打开我的 html 文件。只是一个空白页。

那么如何打开带有参数的 html 文件?

【问题讨论】:

    标签: c# windows-services createprocessasuser system-services


    【解决方案1】:

    删除

    appPath = appPath + " " + cmdLine;
    

    并将 cmlLine 参数替换为 CreateProcessAsUser

    $@"""{appPath}"" {cmdLine}"
    

    我们遇到了同样的问题,花了很多时间解决

    工作示例

        static void Main()
        {
            var url = @"Test.html";
            var kioskMode = url + " --kiosk --incognito --disable-pinch --overscroll-history-navigation=0 ";
    
            StartProcessAsCurrentUser(@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", kioskMode);
        }
    
        public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true)
        {
            var hUserToken = IntPtr.Zero;
            var startInfo = new STARTUPINFO();
            var procInfo = new PROCESS_INFORMATION();
            var pEnv = IntPtr.Zero;
    
            startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
            hUserToken = WindowsIdentity.GetCurrent().Token; //get current user token
    
            var dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint) (visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);
            startInfo.wShowWindow = (short) (visible ? SW.SW_SHOW : SW.SW_HIDE);
            startInfo.lpDesktop = "winsta0\\default";
    
            if (!CreateEnvironmentBlock(out pEnv, hUserToken, 0))
            {
                throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed.");
            }
    
            if (!CreateProcessAsUser(hUserToken,
                appPath, // Application Name
                $@"""{appPath}"" {cmdLine}", // Command Line
                IntPtr.Zero,
                IntPtr.Zero,
                false,
                dwCreationFlags,
                pEnv,
                workDir, // Working directory
                ref startInfo,
                out procInfo))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
    
            return true;
        }
    
        private const int CREATE_NO_WINDOW = 0x08000000;
        private const int CREATE_NEW_CONSOLE = 0x00000010;
        private const int CREATE_UNICODE_ENVIRONMENT = 0x400;
    
        [DllImport("userenv.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, int bInherit);
    
        [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public 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);
    
        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }
    
        public enum SW
        {
            SW_HIDE = 0,
            SW_SHOWNORMAL = 1,
            SW_NORMAL = 1,
            SW_SHOWMINIMIZED = 2,
            SW_SHOWMAXIMIZED = 3, // these two enum members actually have the same value
            SW_MAXIMIZE = 3, // assigned to them This is not an error
            SW_SHOWNOACTIVATE = 4,
            SW_SHOW = 5,
            SW_MINIMIZE = 6,
            SW_SHOWMINNOACTIVE = 7,
            SW_SHOWNA = 8,
            SW_RESTORE = 9,
            SW_SHOWDEFAULT = 10,
            SW_FORCEMINIMIZE = 11,
            SW_MAX = 12
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2021-12-23
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      相关资源
      最近更新 更多