Esempio n. 1
0
        /// <summary>
        /// Attempts to kill the streamer process and returns true if the streamer process is closed (even if it wasn't running to start with.  If this method returns false, assume the streamer process is unkillable.
        /// </summary>
        /// <returns></returns>
        private bool Kill()
        {
            Logger.Info("Killing Streamer Process" + (streamer_process == null ? "" : " (PID: " + streamer_process.Id + ")"));
            RaiseOnCloseEvent();

            sm = null;

            if (streamer_process == null)
            {
                return(true);
            }

            streamer_process.Refresh();
            if (streamer_process.HasExited)
            {
                ClearProcessReference();
                return(true);
            }
            try
            {
                streamer_process.CloseMainWindow();
                if (!streamer_process.WaitForExit(1000))                 // Wait up to one second for exit. It SHOULD be much, much faster than this.
                {
                    streamer_process.Kill();
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Debug(ex, "Unable to kill " + Globals.ExecutableNameWithExtension + " process.");
                return(false);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Opens an existing SharedMemoryStream created by another process.
        /// </summary>
        /// <param name="uniqueId">An ID which is unique to this application.</param>
        /// <returns></returns>
        public static SharedMemoryStream OpenSharedMemoryStream(string uniqueId, int ownerProcessId)
        {
            SharedMemoryStream sms = new SharedMemoryStream(false, uniqueId, ownerProcessId);

            return(sms);
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a SharedMemoryStream with the specified ID. Requires the process to be elevated.
        /// Only one process besides this one may open the SharedMemoryStream. If more than one additional process opens the stream, the behavior is undefined.
        /// </summary>
        /// <param name="uniqueId">An ID which is unique to this application.</param>
        /// <returns></returns>
        public static SharedMemoryStream CreateSharedMemoryStream(string uniqueId)
        {
            SharedMemoryStream sms = new SharedMemoryStream(true, uniqueId);

            return(sms);
        }
Esempio n. 4
0
        private void readSharedMemory(object args)
        {
            SharedMemoryStream mySm = (SharedMemoryStream)args;

            try
            {
                while (sm == mySm)
                {
                    try
                    {
                        byte    cmdByte = (byte)sm.ReadByte();
                        Command cmd     = (Command)cmdByte;
                        // Handle message from Streamer process.
                        // TODO: Refactor the responses to use a generic wrapper class, e.g.
                        // AsyncLoadingObject<FragmentedImage> newFrame = ...;
                        // newFrame.Loaded(img);
                        // if (newFrame.Wait(abortFlag, out ...))
                        //	return ...;
                        switch (cmd)
                        {
                        case Command.GetScreenCapture:
                            FragmentedImage img = new FragmentedImage(sm);
                            newFrame.Produce(img);
                            break;

                        case Command.GetDesktopInfo:
                            DesktopInfo di = new DesktopInfo(sm);
                            newDesktopInfo.Produce(di);
                            break;

                        case Command.Error_SyntaxError:
                        case Command.Error_CommandCodeUnknown:
                        case Command.Error_Unspecified:
                        case Command.StartStreaming:
                        case Command.StopStreaming:
                        case Command.AcknowledgeFrame:
                        case Command.ReproduceUserInput:
                        case Command.SetStreamSettings:
                        case Command.GetStreamSettings:
                        default:
                            Logger.Info("Received unexpected byte from Streamer process: " + cmd);
                            // TODO: End the Streamer process now and start a new one, because we have just entered an undefined state.
                            break;
                        }
                    }
                    catch (ThreadAbortException) { throw; }
                    catch (StreamDisconnectedException) { throw; }
                    catch (Exception ex)
                    {
                        Logger.Debug(ex);
                    }
                }
            }
            catch (ThreadAbortException) { }
            catch (StreamDisconnectedException)
            {
                Logger.Info("Read Shared Memory thread detected stream close (" + mySm.uniqueId + ")");
            }
            catch (Exception ex)
            {
                Logger.Debug(ex);
            }
            finally
            {
                Try.Catch(() => { mySm?.Dispose(); });
                RaiseOnCloseEvent();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Checks the status of the streamer process and starts it if necessary. Returns true if the streamer process is active.  Returns false if the streamer process is not active, indicating that other requests will fail.
        /// </summary>
        private bool Maintain()
        {
            try
            {
                // TODO: ProcessHelper.GetConsoleSessionId() does not always return the session ID of the current visible.
                // Example: Hyper-V virtual machines.  Try connecting to SHRD while there is no active Virtual Machine
                // Connection window, then open a Virtual Machine Connection window and it will run under a different
                // session ID than SHRD.  The only apparent fix is to log out the VM session and then the VM connection
                // begins using the same session as SHRD.
                // We perhaps need a way to manually connect to a specific session.  I envision a GUI where you can see a
                // list of sessions and the processes running under them, to help you choose which session to connect to.
                int consoleSessionId = ProcessHelper.GetConsoleSessionId();
                if (consoleSessionId != lastConsoleSessionId)
                {
                    if (lastConsoleSessionId != -2)
                    {
                        Logger.Info("Detected change in console session ID from " + lastConsoleSessionId + " to " + consoleSessionId + ". This StreamerController will now close.");
                        Kill();
                        return(false);
                    }
                    else
                    {
                        lastConsoleSessionId = consoleSessionId;
                    }
                }
                if (consoleSessionId == -1)
                {
                    Logger.Info("consoleSessionId -1 (no session attached to physical console)");
                    Kill();
                    return(false);
                }
                if (streamer_process != null)
                {
                    streamer_process.Refresh();
                    if (streamer_process.HasExited)
                    {
                        ClearProcessReference();
                        RaiseOnCloseEvent();
                        return(false);
                    }
                    else if (streamer_process.SessionId == consoleSessionId)
                    {
                        return(true);
                    }
                    else
                    {
                        Logger.Info("streamer_process.SessionId (" + streamer_process.SessionId + ") != consoleSessionId (" + consoleSessionId + ")");
                        Kill();                         // Session Id is no longer current
                        return(false);
                    }
                }

                // If we reach this point, we need to start the streamer process.
                string sharedMemUniqueId = "Stream" + Interlocked.Increment(ref numberOfTimesStreamerHasBeenStarted);
                sm = SharedMemoryStream.CreateSharedMemoryStream(sharedMemUniqueId);
                StartSharedMemoryReadingThread(sharedMemUniqueId);

                string       path = Globals.ApplicationDirectoryBase;
                StreamerArgs args = new StreamerArgs(this_process_pid, sharedMemUniqueId);
                if (Environment.UserInteractive)
                {
                    ProcessStartInfo psi = new ProcessStartInfo(path + Globals.ExecutableNameWithExtension, args.ToString());
                    psi.UseShellExecute  = false;
                    psi.WorkingDirectory = path;
                    streamer_process     = Process.Start(psi);
                    sm.otherProcessPid   = streamer_process.Id;
                }
                else
                {
                    // TODO: Add a method for enumerating and choosing the Windows Session ID to open the process with.
                    int streamer_pid = sm.otherProcessPid = ProcessHelper.ExecuteInteractive(path + Globals.ExecutableNameWithExtension, args.ToString(), path);
                    streamer_process = ProcessHelper.GetProcByID(streamer_pid);
                }
                Logger.Info("Started streamer process (PID: " + streamer_process.Id + ", Shared Memory ID: " + sharedMemUniqueId + ")");
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Debug(ex);
                return(false);
            }
        }