5
// Michael Hutchinson <mhutchinson@novell.com>
7
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
using System.Threading;
32
using MonoDevelop.Core;
34
namespace MonoDevelop.AspNet.Gui
38
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.Services.PlatformService.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) {
133
} 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;