public async Task<WorkingAgent> GetCompatibleAgentFromList(RenderConfiguration configuration, List<Agent> list)
        {
            WorkingAgent compatible = null;            

            foreach (Agent info in list)
            {
                if (compatible == null)
                {
                    WorkingAgent worker = new WorkingAgent(configuration);

                    try
                    {
                        RenderMessage msg = await worker.Connect(info);

                        if (msg == RenderMessage.Supported)
                        {
                            compatible = worker;
                            this.currentCompatibleAgent = info;
                        }
                    }
                    catch (AgentNotReachableException)
                    {
                        if (this.OnAgentNotReachable != null)
                        {
                            this.OnAgentNotReachable(this, info);
                        }
                    }
                }
            }

            return compatible;
        }
        public async Task<WorkingAgent> GetCompatibleAgent(RenderConfiguration configuration)
        {
            List<Agent> allAgents = new List<Agent>() { };

            if (currentCompatibleAgent != null)
            {
                allAgents.Add(currentCompatibleAgent);
            }

            allAgents.AddRange(this.AvailableAgents.ToList());

            return await this.GetCompatibleAgentFromList(configuration, allAgents);
        }
        /// <summary>
        /// Continuously captures images of the given resource and fires the <see cref="ScreenCapture.OnImageCaptured"/> event.
        /// <see cref="FileResource"/>s are opened with their default program.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown if a already capturing a window or if the process has no UI.</exception>
        /// <exception cref="ProcessStartupException">Thrown if the process took to long to start up (<seealso cref="ScreenCapture.PROCESS_STARTUP_WAIT_DURATION"/>).</exception>
        /// <exception cref="ArgumentException">
        /// Thrown if config's update interval is less than 0
        /// or the process for a <see cref="FileResource"/> cannot be started
        /// or a <see cref="ProcessResource"/>s PID cannot be found.</exception>
        /// <exception cref="NotSupportedException">Thrown if the job's resource is not of type <see cref="FileResource"/> or <see cref="ProcessResource"/>.</exception>
        public void StartCapture(RenderConfiguration config)
        {
			Process proc = null;
            IResource resource = config.JobToDo.Resource;

            if (this.IsRunning)
            {
                throw new InvalidOperationException("A capturing process is already started.");
            }

            if (config.UpdateInterval < 0)
            {
                throw new ArgumentException("The update interval must not be less than 0.");
            }

            if (resource is FileResource)
			{
                string path = ((FileResource)resource).Path;
                string extension = System.IO.Path.GetExtension(path);

                // TODO start PowerPoint files as fullscreen slideshow
                if (extension == ".ppt" || extension == ".pptx")
                {
                    proc = new Process();
                    proc.StartInfo.FileName = "powerpnt.exe";
                    proc.StartInfo.Arguments = string.Format("/S \"{0}\"", path);
                }
                else
                {
                    proc = new Process();
                    proc.StartInfo.FileName = path;
                }

                try
                {
                    proc.Start();
                    this.selfStartedProcess = true;
                }
                catch
                {
                    throw new ArgumentException("Failed to start the process for the FileResource.");
                }
            }
			else if (resource is ProcessResource)
			{
				int pid = ((ProcessResource)resource).ProcessID;
                proc = Process.GetProcessById(pid);
            }
			else
			{
                throw new NotSupportedException("Only capturing of jobs with FileResource and ProcessResource is supported.");
			}
            
            if (!proc.WaitForInputIdle(PROCESS_STARTUP_WAIT_DURATION))
            {
                throw new ProcessStartupException();
            }

            if (proc.MainWindowHandle == IntPtr.Zero)
            {
                throw new InvalidOperationException("Cannot capture images of a window-less process.");
            }

            // bring the window to the "bottommost" position
            SetWindowPos(proc.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
            
            Thread capturer = new Thread(new ParameterizedThreadStart(this.Capture));
            this.captureArgs = new CaptureThreadArgs(proc, config);
            capturer.IsBackground = true;
            capturer.Start(this.captureArgs);
            this.IsRunning = true;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CaptureThreadArgs"/> class.
        /// </summary>
        public CaptureThreadArgs(Process process, RenderConfiguration configuration)
        {
            this.Process = process;
			this.Configuration = configuration;
            this.Exit = false;
        }
 public WorkingAgent(RenderConfiguration configuration)
 {
     this.Configuration = configuration;
 }
        private RenderConfiguration GetNewRenderConfiguration(Job jobToDo)
        {
            RenderConfiguration config = new RenderConfiguration();
            config.RenderJobID = Guid.NewGuid();
            config.JobID = this.configuration.JobID;
            config.JobToDo = jobToDo;
            config.RenderWidth = (int)this.renderSize.Width / 2;
            config.RenderHeight = (int)this.renderSize.Height / 2;

            config.UpdateInterval = 30;
            config.IgnoreEqualImages = true;

            return config;
        }
 public RCS_Render_Job(RenderConfiguration configuration, RemoteType remote) : base(remote)
 {
     this.Configuration = configuration;
 }