26
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
using MonoDevelop.Core;
30
using MonoDevelop.Core.Gui;
31
using MonoDevelop.Core.ProgressMonitoring;
32
using MonoDevelop.Core.Execution;
30
using System.Threading;
32
using MonoDevelop.Core;
34
36
namespace MonoDevelop.AspNet.Gui
38
39
public static class BrowserLauncher
40
public static BrowserLauncherOperation LaunchWhenReady (string url, BrowserLaunchHandler browserHandler)
42
return new BrowserLauncherOperation (url, browserHandler);
45
public static void LaunchDefaultBrowser (string url)
47
MonoDevelop.Core.Gui.DesktopService.ShowUrl (url);
50
public static BrowserLauncherOperation LaunchWhenReady (string url)
52
return new BrowserLauncherOperation (url, LaunchDefaultBrowser);
56
public delegate void BrowserLaunchHandler (string url);
58
public class BrowserLauncherOperation : IAsyncOperation
63
readonly BrowserLaunchHandler browserHandler;
64
Thread launcherThread;
67
public BrowserLauncherOperation (string url, BrowserLaunchHandler browserHandler)
69
if (browserHandler == null)
70
throw new ArgumentNullException ("browserHandler");
72
throw new ArgumentNullException ("url");
75
this.browserHandler = browserHandler;
76
if (url.StartsWith ("http://")) {
77
launcherThread = new Thread (new ThreadStart (LaunchWebBrowser));
78
launcherThread.Start ();
86
//confirm we can connect to server before opening browser; wait up to ten seconds
87
void LaunchWebBrowser ()
90
//wait a bit for server to start
93
//try to contact web server several times, because server may take a while to start
95
int timeout = 8000; //ms
98
for (int i = 0; i < noOfRequests; i++) {
99
System.Net.WebRequest req = null;
100
System.Net.WebResponse resp = null;
103
req = System.Net.HttpWebRequest.Create (url);
104
req.Timeout = timeout;
105
resp = req.GetResponse ();
106
} catch (System.Net.WebException exp) {
108
// server has returned 404, 500 etc, which user will still want to see
109
if (exp.Status == System.Net.WebExceptionStatus.ProtocolError) {
112
//final request has failed
113
} else if (i >= (noOfRequests - 1)) {
114
string message = GettextCatalog.GetString ("Could not connect to webserver {0}", url);
115
throw new UserException (message, exp.ToString ());
117
//we still have requests to go, so cancel the current one and sleep for a bit
126
//TODO: a choice of browsers
127
browserHandler (url);
132
} catch (ThreadAbortException) {
41
public static IProcessAsyncOperation LaunchDefaultBrowser (string url)
44
DesktopService.ShowUrl (url);
45
return NullProcessAsyncOperation.Success;
133
46
} catch (Exception ex) {
134
//don't want any exceptions leaking out the top of the thread, as they'd crash the runtime
135
LoggingService.LogError ("Unhandled error in browser launcher thread", ex);
141
public Exception Error {
142
get { return error; }
145
public void Cancel ()
147
//FIXME: should we try something more graceful than a thread abort? Tricky with the 2s waits...
148
if (launcherThread != null && launcherThread.IsAlive && launcherThread.ThreadState != ThreadState.AbortRequested)
149
launcherThread.Abort ();
152
public void WaitForCompleted ()
154
if (launcherThread != null && launcherThread.IsAlive)
155
launcherThread.Join ();
158
public event OperationHandler Completed {
160
bool raiseNow = false;
165
completedEvent += value;
172
completedEvent -= value;
177
public bool Success {
178
get { return successful; }
181
public bool SuccessWithWarnings {
182
get { return false; }
185
public bool IsCompleted {
186
get { return completed; }
189
throw new InvalidOperationException ();
191
if (completedEvent != null)
192
completedEvent (this);
196
event OperationHandler completedEvent;
47
MessageService.ShowError (GettextCatalog.GetString ("Error launching web browser"), ex.ToString ());
48
return NullProcessAsyncOperation.Failure;