admin管理员组

文章数量:1415645

I am trying to get my current location( latitude and longitude ) in web application it works fine with following HTML5 code.

<!DOCTYPE html>
<html>
<body>
    <p id="demo">Click the button to get your coordinates:</p>
    <button onclick="getLocation()">Try It</button>
    <script>
        var x = document.getElementById("demo");
        function getLocation()
        {
            if (navigator.geolocation)
            {
                navigator.geolocation.getCurrentPosition(showPosition);
            }
            else
            {
                x.innerHTML = "Geolocation is not supported by this browser.";
            }
        }

        function showPosition(position)
        {
            x.innerHTML="Latitude: " + position.coords.latitude + 
                "<br>Longitude: " + position.coords.longitude;  
        }
    </script>
</body>
</html>

But I want to get latitude and longitude of user in desktop app. There is no option to use JavaScript in desktop app, so I am trying to access it using the web browser. When I am trying to access the above created web page from dektop application using webbrowser control (IE10) it doesn't share physical location, and nothing happens when I call the script by button click.

Can anyone help me to get my location(latitude and longitude) in a desktop app(C#)?

I am trying to get my current location( latitude and longitude ) in web application it works fine with following HTML5 code.

<!DOCTYPE html>
<html>
<body>
    <p id="demo">Click the button to get your coordinates:</p>
    <button onclick="getLocation()">Try It</button>
    <script>
        var x = document.getElementById("demo");
        function getLocation()
        {
            if (navigator.geolocation)
            {
                navigator.geolocation.getCurrentPosition(showPosition);
            }
            else
            {
                x.innerHTML = "Geolocation is not supported by this browser.";
            }
        }

        function showPosition(position)
        {
            x.innerHTML="Latitude: " + position.coords.latitude + 
                "<br>Longitude: " + position.coords.longitude;  
        }
    </script>
</body>
</html>

But I want to get latitude and longitude of user in desktop app. There is no option to use JavaScript in desktop app, so I am trying to access it using the web browser. When I am trying to access the above created web page from dektop application using webbrowser control (IE10) it doesn't share physical location, and nothing happens when I call the script by button click.

Can anyone help me to get my location(latitude and longitude) in a desktop app(C#)?

Share Improve this question edited Jan 21, 2013 at 9:29 Tom van Enckevort 4,1981 gold badge26 silver badges41 bronze badges asked Jan 21, 2013 at 9:21 user1996284user1996284 311 silver badge2 bronze badges 7
  • Have you tried to use the method overload that shows the error? You can see the code here. – Alex Filipovici Commented Jan 21, 2013 at 9:51
  • yes,am try that too.but my app doesn't show even that error message – user1996284 Commented Jan 21, 2013 at 10:35
  • What is the JS call to document.documentMode returning? – Alex Filipovici Commented Jan 21, 2013 at 11:28
  • its doesn't return anything.. – user1996284 Commented Jan 22, 2013 at 4:45
  • Is JavaScript working at all for your WebBrowser control? – Alex Filipovici Commented Jan 22, 2013 at 8:01
 |  Show 2 more ments

2 Answers 2

Reset to default 3

I'm posting another answer to the question as this involves a pletely different approach.

The Context

When JavaScript tries to access the location object in IE 10 you are presented with the security bar asking for you to allow the access to your location. The difference for a file which is on the local drive or a network share is that you are not presented with the option to always allow access, but only once (Allow once).

For whatever reason, this security bar doesn't show up in the WebBrowser control (even if I've tried setting the Information Bar Handling for the aplication's .exe, but it seems not to have any effect).

This is why every time when the script executes nothing happens in the web browser control. It is actually blocked by the information bar.

The Solution

What needs to be done:

  1. Emulate a web server inside the application. I've used a Simple C# Web Server class to serve the content. This way, even if there is no web server on the local machine, we may intercept requests to a specific URL address and port and serve the content we want to.

  2. Add the test1.html document to the project and use it's content in the server response. Just add the file into your project, next to the "Program.cs" file and set it's Copy to Output Directory property value to Copy always.

How It Works

First, we need to instantiate a web browser control. Then, navigate to the test1.html file. When the document is loaded, we first check if the web server is not instantiated. If this, we create an instance of it and then we read and store the web browser's HTMl source in the response variable, which we pass to the WebServer constructor.

The http://localhost:9999 registers the HttpListener to that prefix, so every request to this address will be served by our simple web server.

Next, we navigate to that address. When the web server will receive the request, it will deliver the content of the _staticContent variable, which had it's value assigned in the web server's constructor.

After the server delivers the document to the web browser, the webBrowser1_DocumentCompleted handler is triggered. But this time, we already have the web server's instance, so execution goes through the else branch. The important thing to notice is that we will asynchronously wait for the JavaScript to execute, get the location and save it to the hidden input elements in the HTML.

One important remark: the first time you launch the application you will not get any location. You first have to leave the application open, so that you have the custom HTTP listener available, and then, perform the steps I described in my other answer, the browsing location being http://localhost:9999. Once you do that, close and reopen the application.

That's it. Everytime you run the application, you will get the location coordinates in a message box.

The Form1 class file (Form1.cs):

public partial class Form1 : Form
{

    WebServer _ws;
    WebBrowser _webBrowser1;

    public Form1()
    {
        InitializeComponent();
        _webBrowser1 = new WebBrowser();
        _webBrowser1.Visible = false;
        var location = Assembly.GetExecutingAssembly().Location;
        _webBrowser1.Navigate(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\test1.html");
        _webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    async void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (_ws == null)
        {
            var html = _webBrowser1.Document.GetElementsByTagName("html");
            var response = html[0].OuterHtml;
            _ws = new WebServer(response, "http://localhost:9999/");
            _ws.Run();
            _webBrowser1.Navigate("http://localhost:9999/");
        }
        else
        {
            string latitude = "";
            string longitude = "";

            await Task.Factory.StartNew(() =>
            {
                while (string.IsNullOrEmpty(latitude))
                {
                    System.Threading.Thread.Sleep(1000);

                    if (this.InvokeRequired)
                    {
                        this.Invoke((MethodInvoker)delegate
                        {
                            var latitudeEl = _webBrowser1.Document.GetElementById("latitude");
                            var longitudeEl = _webBrowser1.Document.GetElementById("longitude");

                            latitude = latitudeEl.GetAttribute("value");
                            longitude = longitudeEl.GetAttribute("value");
                        });
                    }
                }
            });
            MessageBox.Show(String.Format("Latitude: {0} Longitude: {1}", latitude, longitude));
        }
    }

    // credits for this class go to David
    // http://www.codehosting/blog/BlogEngine/post/Simple-C-Web-Server.aspx
    public class WebServer
    {
        private readonly HttpListener _listener = new HttpListener();
        static string _staticContent;

        public WebServer(string[] prefixes, string content)
        {
            _staticContent = content;
            foreach (string s in prefixes)
                _listener.Prefixes.Add(s);
            _listener.Start();
        }

        public WebServer(string content, params string[] prefixes)
            : this(prefixes,  content) { }

        public void Run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                try
                {
                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem((c) =>
                        {
                            var ctx = c as HttpListenerContext;
                            try
                            {
                                byte[] buf = Encoding.UTF8.GetBytes(_staticContent);
                                ctx.Response.ContentLength64 = buf.Length;
                                ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                            }
                            catch { } // suppress any exceptions
                            finally
                            {
                                // always close the stream
                                ctx.Response.OutputStream.Close();
                            }
                        }, _listener.GetContext());
                    }
                }
                catch { } // suppress any exceptions
            });
        }

        public void Stop()
        {
            _listener.Stop();
            _listener.Close();
        }
    }
}

The HTML source (test1.html)

<html xmlns="http://www.w3/1999/xhtml">
<head runat="server">
    <title></title>
    <meta http-equiv="X-UA-Compatible" content="IE=10" />
    <script type="text/javascript">
        window.onload = function () {
            var latitude = document.getElementById("latitude");
            var longitude = document.getElementById("longitude");

            function getLocation() {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(showPosition);
                }
                else { }
            }
            function showPosition(position) {
                latitude.value = position.coords.latitude;
                longitude.value = position.coords.longitude;
            }
            getLocation();
        }
    </script>
</head>
<body>
    <input type="hidden" id="latitude" />
    <input type="hidden" id="longitude" />
</body>
</html>

This could happen because the WebBrowser control uses the patibility mode for a previous version of Internet Explorer.

You have the possibility to set the default emulation mode for Internet Explorer per application by using the FEATURE_BROWSER_EMULATION feature. This is how you actually set the patibility mode for the WebBrowser control in your own application.

You may follow the indications from the link below in order to configure it:

Internet Feature Controls (B..C)

[UPDATE]

  1. Go to Internet Options -> Privacy
  2. Under the Location section, make sure that Never allow websites to request your physical location is unchecked
  3. Click on Clear Sites
  4. Open Internet Explorer (not your application) and browse to the URL of the file containing the geolocation script
  5. Trigger the getLocation() function (in your case, click on the Try It button)
  6. When the browser shows the security bar in the lower part of the window, containing the yourSite wants to know your physical location., click on Options for this site and choose Always allow.

That would be it.

本文标签: javascriptC desktop application doesn39t share my physical locationStack Overflow