private static void mainThreadRunner() { try { screenCapturer = new AdvScreenCapture(); dxgiDuplicator = new DxgiOutputDuplicator(0, 0); inputEmulator = new InputEmulator(); Logger.Info("Application start shared memory id " + streamerArgs.SharedMemoryId); int ownerPID = streamerArgs.ServiceProcessId == null ? 0 : streamerArgs.ServiceProcessId.Value; using (SharedMemoryStream sm = SharedMemoryStream.OpenSharedMemoryStream(streamerArgs.SharedMemoryId, ownerPID)) { try { static_sm = sm; thrDesktopCapture.Start(); while (!isExiting) { Command commandCode = (Command)sm.ReadByte(); // Handle switch (commandCode) { case Command.GetScreenCapture: ImgFlags imgFlags = (ImgFlags)sm.ReadByte(); byte jpegQuality = (byte)sm.ReadByte(); desktopCaptureTasks.Enqueue(new DesktopCaptureTask(imgFlags, jpegQuality)); break; //case Command.CaptureCompressedDesktopImage: // CaptureCompressedDesktopImage(sm); // break; case Command.ReproduceUserInput: inputEmulator.EmulateInput(sm); break; case Command.GetDesktopInfo: lock (sm) { desktopInfo.WriteToDataStream(sm); } break; case Command.KeepAlive: break; default: Logger.Debug("Unsupported command code received: " + commandCode); lock (sm) { sm.WriteByte((byte)Command.Error_CommandCodeUnknown); } break; } } } finally { static_sm = null; } } } catch (ThreadAbortException) { } catch (StreamDisconnectedException ex) { Logger.Info("Exiting because: " + ex.Message); } catch (Exception ex) { Logger.Debug(ex); Logger.Info("Exiting due to main thread runner exception"); } finally { Try.Catch(() => { dxgiDuplicator?.Dispose(); }); Try.Catch(() => { screenCapturer?.Dispose(); }); //Try.Catch(() => { inputEmulator?.Dispose(); }); RobustExit(); } }