/// <summary> /// Starts a process or URI via the Windows shell. /// </summary> /// <param name="startInfo"></param> /// <param name="callback"></param> /// <returns></returns> public static WardenProcess StartByShell(WardenStartInfo startInfo, Action <bool> callback = null) { if (!Initialized) { throw new WardenManageException(Resources.Exception_Not_Initialized); } if (string.IsNullOrWhiteSpace(startInfo.FileName)) { throw new ArgumentException("fileName cannot be empty."); } if (startInfo.Track && string.IsNullOrWhiteSpace(startInfo.TargetFileName)) { throw new ArgumentException("targetFileName cannot be empty."); } if (CheckForWardenProcess(startInfo.TargetFileName, out var existingProcess)) { return(existingProcess); } if (string.IsNullOrWhiteSpace(startInfo.Arguments)) { startInfo.Arguments = string.Empty; } var shellStartInfo = new ShellStartInfo(startInfo.FileName, startInfo.Arguments, startInfo.WorkingDirectory) { Verb = startInfo.RaisePrivileges ? "runas" : "open" }; if (startInfo.Track) { var key = Guid.NewGuid(); var proc = new WardenProcess(System.IO.Path.GetFileNameWithoutExtension(startInfo.TargetFileName), GenerateProcessId(), startInfo.TargetFileName, ProcessState.Alive, startInfo.Arguments.SplitSpace(), startInfo.Filters) { FoundCallback = callback }; if (ManagedProcesses.TryAdd(key, proc)) { Api.StartByShell(shellStartInfo); if (ManagedProcesses.TryGetValue(key, out var process)) { return(process); } } } Api.StartByShell(shellStartInfo); return(null); }
/// <summary> /// Starts process using ShellExecute so it launches with the lowest privileges or resolves URIs /// </summary> /// <param name="startInfo">Contains the information about the <see cref="Process" /> to be started</param> public static void StartByShell(ShellStartInfo startInfo) { var emptyObject = new object(); object shellWindows = null; object desktopWindow = null; object desktopBrowser = null; object desktopView = null; object backgroundFolderView = null; object applicationDispatch = null; var shellWindowsType = Type.GetTypeFromCLSID(ShellWindowsServer, false); if (shellWindowsType == null) { throw new WardenLaunchException("This operation is not available in this environment."); } try { shellWindows = Activator.CreateInstance(shellWindowsType); desktopWindow = ((IShellWindows)shellWindows).FindWindowSW( ref emptyObject, ref emptyObject, ShellWindowsClass.Desktop, out _, ShellWindowsFindOptions.NeedDispatch ); ((IServiceProvider)desktopWindow).QueryService( TopLevelBrowser, typeof(IShellBrowser).GUID, out desktopBrowser ); ((IShellBrowser)desktopBrowser).QueryActiveShellView(out desktopView); ((IShellView)desktopView).GetItemObject( ShellViewGetItemObject.Background, typeof(IDispatch).GUID, out backgroundFolderView ); applicationDispatch = ((IShellFolderViewDual)backgroundFolderView).Application; var showFlags = new object(); switch (startInfo.WindowStyle) { case ProcessWindowStyle.Normal: showFlags = ShellDispatchExecuteShowFlags.Normal; break; case ProcessWindowStyle.Hidden: showFlags = ShellDispatchExecuteShowFlags.Hidden; break; case ProcessWindowStyle.Minimized: showFlags = ShellDispatchExecuteShowFlags.Minimized; break; case ProcessWindowStyle.Maximized: showFlags = ShellDispatchExecuteShowFlags.Maximized; break; } ((IShellDispatch2)applicationDispatch).ShellExecute( startInfo.Address, startInfo.Arguments, startInfo.WorkingDirectory, startInfo.Verb ?? emptyObject, showFlags ); } catch (Exception e) { throw new WardenLaunchException("Failed to start application.", e); } finally { if (applicationDispatch != null) { Marshal.ReleaseComObject(applicationDispatch); } if (backgroundFolderView != null) { Marshal.ReleaseComObject(backgroundFolderView); } if (desktopView != null) { Marshal.ReleaseComObject(desktopView); } if (desktopBrowser != null) { Marshal.ReleaseComObject(desktopBrowser); } if (desktopWindow != null) { Marshal.ReleaseComObject(desktopWindow); } if (shellWindows != null) { Marshal.ReleaseComObject(shellWindows); } } }