private void workerThread_DoWork(object sender, DoWorkEventArgs e) { try { log.Write(TraceLevel.Info, "Adding Windows Firewall Rule"); try { WindowsFirewall.AuthorizeProgram(AppMain.DisplayName, new FileInfo(Assembly.GetExecutingAssembly().Location)); } catch (Exception ex) { log.Write(TraceLevel.Error, "Failed to add rule to Windows firewall", ex); } if (_worker.CancellationPending) { return; } _worker.ReportProgress(10, "Starting Miracle Server"); log.Write(TraceLevel.Info, "Starting Miracle Server"); _vncManager.StartVncServer(); if (_worker.CancellationPending) { return; } _worker.ReportProgress(30, "Detecting NAT/Firewall"); log.Write(TraceLevel.Info, "Detecting NAT/Firewall"); _apiClient = new MiracleSticksAPIClient("BasicHttpBinding_IMiracleSticksAPI"); // Are we behind a UPnP-enabled NAT/firewall? if (UPnP.NatDeviceFound) { try { if (_worker.CancellationPending) { return; } _worker.ReportProgress(50, "Configuring NAT/Firewall"); log.Write(TraceLevel.Info, "Configuring NAT/Firewall"); _externalEP = UPnP.GetExternalEndpoint(ConfigManager.Data.Port); } catch (Exception ex) { log.Write(TraceLevel.Warning, "UPnP Error", ex); } if (_externalEP == null) { if (_worker.CancellationPending) { return; } log.Write(TraceLevel.Info, "Creating UPnP port mapping"); try { _externalEP = UPnP.MapPort(ConfigManager.Data.Port, ConfigManager.Data.Port); } catch (Exception ex) { log.Write(TraceLevel.Warning, "UPnP Error", ex); } if (_externalEP == null) { log.Write(TraceLevel.Warning, "UPnP port mapping failed"); e.Result = RegisterForPacketRelay(); } } else { log.Write(TraceLevel.Info, "UPnP port mapping already exists"); } if (_externalEP != null) { if (_worker.CancellationPending) { return; } _worker.ReportProgress(70, "Verifying NAT/Firewall Configuration"); // See if the server can access our listen port bool pingSuccess; try { var pingResponse = _apiClient.PortTest(new PortTestRequest { Port = _externalEP.Port }); pingSuccess = pingResponse.Success; } catch (EndpointNotFoundException ex) { log.Write(TraceLevel.Error, "Failed to connect to MiracleSticks service", ex); e.Result = new Exception("Failed to connect to MiracleSticks service"); return; } if (pingSuccess && !AppMain.DebugMode) { e.Result = RegisterForDirectConnection(_externalEP); } else { log.Write(TraceLevel.Warning, "Port test failed"); e.Result = RegisterForPacketRelay(); } } } else { if (_worker.CancellationPending) { return; } log.Write(TraceLevel.Info, "No NAT/firewall detected"); // See if the server can access our listen port bool pingSuccess; try { var pingResponse = _apiClient.PortTest(new PortTestRequest { Port = ConfigManager.Data.Port }); pingSuccess = pingResponse.Success; } catch (EndpointNotFoundException ex) { log.Write(TraceLevel.Error, "Failed to connect to MiracleSticks service", ex); e.Result = new Exception("Failed to connect to MiracleSticks service"); return; } if (pingSuccess && !AppMain.DebugMode) { IPEndPoint ep = new IPEndPoint(NetworkAdapters.GetRoutedInterface(), ConfigManager.Data.Port); e.Result = RegisterForDirectConnection(ep); } else { log.Write(TraceLevel.Warning, "Port test failed"); e.Result = RegisterForPacketRelay(); } } } catch (ThreadAbortException) { throw; } catch (ThreadInterruptedException) { throw; } catch (Exception ex) { log.Write(TraceLevel.Error, "Fatal error", ex); e.Result = ex; } }