Beispiel #1
0
        void StartGuiProcess(int sessionId)
        {
            TerminateProcess(ref mGuiProcess, ref mGuiMan, false);
            mDesktopGuiIsOn = "";

            var desktop = mDesktopFromWatcher;

            mDesktopGuiIsOn = desktop;
            var pipeName = "OpenViewtop_gui_" + Util.GenerateRandomId();

            // When on the default desktop, run as the user so the clipboard works properly.
            // For other desktops we need to run as system so the GUI has permission to copy the screen.
            // TBD: Seems like there should be a better way to do this
            WtsProcessType processType = desktop.ToLower() != DEFAULT_DESKTOP.ToLower() || sessionId == 0
                                            ? WtsProcessType.System : WtsProcessType.UserFallbackToSystem;

            processType |= WtsProcessType.Admin | WtsProcessType.UIAccess;

            // Mange process communications
            Log.Write("*** Starting GUI: Session=" + sessionId + ", User="******", Desktop=" + desktop + ", Pipe=" + pipeName);
            mGuiMan = new ProcessManager(pipeName, true);
            Task.Run(() => { ProcessRemoteCommunications(mGuiMan, "GUI"); });

            mGuiProcess = WtsProcess.StartInSession(
                sessionId, processType, System.Windows.Forms.Application.ExecutablePath,
                Program.PARAM_GUI + " "
                + Program.PARAM_CONTROL_PIPE + " " + pipeName
                + " " + Program.PARAM_DESKTOP + " " + desktop, desktop);
        }
Beispiel #2
0
 /// <summary>
 /// Don't launch using Process.Start, or else it runs as "System"
 /// </summary>
 void ProcessStartAsLoggedOnUser(string fileName)
 {
     try
     {
         // Launch from helper task running as the user, also with the user environment
         // NOTE: This fails unless it's running in the system accont
         WtsProcess.StartInSession(Wts.GetActiveConsoleSessionId(), WtsProcessType.User,
                                   Application.ExecutablePath, Program.PARAM_START_BROWSER + " \"" + fileName + "\"").Dispose();
     }
     catch
     {
         // NOTE: New versions run in as the logged on user and the above code fails.
         Process.Start(fileName);
     }
 }
Beispiel #3
0
        void StartDesktopWatcherProcess(int sessionId)
        {
            TerminateProcess(ref mDesktopProcess, ref mDesktopMan, false);
            mDesktopFromWatcher = "";

            // Create new process
            var pipeName = "OpenViewtop_desktop_" + Util.GenerateRandomId();

            // Manage communications
            Log.Write("*** Starting DESKTOP: Session=" + sessionId + ", User="******", Pipe=" + pipeName);
            mDesktopMan = new ProcessManager(pipeName, true);
            Task.Run(() => { ProcessRemoteCommunications(mDesktopMan, "DESKTOP"); });

            mDesktopProcess = WtsProcess.StartInSession(
                sessionId, WtsProcessType.System,
                System.Windows.Forms.Application.ExecutablePath,
                Program.PARAM_WATCH_DESKTOP + " " + Program.PARAM_CONTROL_PIPE + " " + pipeName);
        }
Beispiel #4
0
        /// <summary>
        /// End the task gracefully if possible, forcefully if necessesary.
        /// Disposes both the pipe and the process when done.
        /// Wait up to timeoutMs milliseconds for the application to close itself.
        /// This is optionally a blocking call, but can also be a "fire and forget"
        /// function by setting block=false.
        /// </summary>
        void TerminateProcess(ref WtsProcess refProcess, ref ProcessManager refManager, bool block)
        {
            var process = refProcess;
            var manager = refManager;

            refProcess = null;
            refManager = null;

            // Quick exit if process is not running
            if (process == null || !process.IsRunning)
            {
                if (process != null)
                {
                    process.Dispose();
                }
                if (manager != null)
                {
                    manager.Close();
                }
                return;
            }

            // Force kill the process if the pipe is not connected
            if (manager == null || !manager.IsConnected)
            {
                // NOTE: Pipe was connected by WaitForPipeCommand
                Log.Write("FORCE KILL process because pipe is not connected: Pipe=" + manager.PipeName);
                process.Terminate(0);
                process.Dispose();
                if (manager != null)
                {
                    manager.Close();
                }
                return;
            }

            // Send the process a request to close in background thread
            Log.Write("Closing process: Pipe=" + manager.PipeName);
            Task.Run(async() =>
            {
                try
                {
                    await manager.SendCommandAsync(ProcessManager.COMMAND_CLOSE);
                }
                catch (Exception ex)
                {
                    Log.Write("Exception sending close command", ex);
                }
            });

            // Wait for it to exit gracefully, but kill it if still running after the timeout
            var task = Task.Run(async() =>
            {
                try
                {
                    // Give it up to one second to kill itslef
                    var now = DateTime.Now;
                    while ((DateTime.Now - now).TotalMilliseconds < PROCESS_TERMINATE_TIMEOUT_MS && process.IsRunning)
                    {
                        await Task.Delay(10);
                    }

                    if (process.IsRunning)
                    {
                        Log.Write("FORCE KILL process after sending cose command: Pipe=" + manager.PipeName);
                        process.Terminate(0);
                    }
                    else
                    {
                        Log.Write("Process closed gracefully: Pipe=" + manager.PipeName);
                    }
                    process.Dispose();
                    manager.Close();
                }
                catch (Exception ex)
                {
                    Log.Write("Cant kill process: Pipe=" + manager.PipeName, ex);
                }
            });

            if (block)
            {
                task.Wait();
            }
        }