3

Webアプリケーションで現在地(緯度と経度)を取得しようとしていますが、次のHTML5コードで正常に機能します。

<!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>

しかし、デスクトップアプリでユーザーの緯度と経度を取得したいと思います。デスクトップアプリでJavaScriptを使用するオプションがないため、Webブラウザーを使用してJavaScriptにアクセスしようとしています。webbrowser control(IE10)を使用してdektopアプリケーションから上記で作成したWebページにアクセスしようとすると、物理的な場所が共有されず、ボタンをクリックしてスクリプトを呼び出しても何も起こりません。

デスクトップアプリ(C#)で自分の位置(緯度と経度)を取得するのを誰かが手伝ってくれますか?

4

2 に答える 2

2

これにはまったく異なるアプローチが含まれているため、質問に対する別の回答を投稿しています。

コンテキスト

JavaScript が IE 10 の場所オブジェクトにアクセスしようとすると、場所へのアクセスを許可するように求めるセキュリティ バーが表示されます。ローカル ドライブまたはネットワーク共有にあるファイルの違いは、アクセスを常に許可するオプションが表示されず、1 回だけ許可する (一度だけ許可する) ことです。

なんらかの理由で、このセキュリティ バーはコントロールに表示されません(アプリケーションの の情報バーの処理WebBrowserを設定しようとしても、効果がないようです)。.exe

これが、スクリプトが実行されるたびに、Web ブラウザー コントロールで何も起こらない理由です。実際には情報バーによってブロックされています。

ソリューション

何をする必要がありますか:

  1. アプリケーション内で Web サーバーをエミュレートします。コンテンツを提供するために、単純な C# Web サーバークラスを使用しました。このように、ローカル マシンに Web サーバーがない場合でも、特定の URL アドレスとポートへの要求を傍受し、必要なコンテンツを提供することができます。

  2. ドキュメントをプロジェクトに追加し、そのtest1.htmlコンテンツをサーバー レスポンスで使用します。「Program.cs」ファイルの横にあるプロジェクトにファイルを追加し、そのCopy to Output Directoryプロパティ値をCopy alwaysに設定するだけです。

使い方

まず、Web ブラウザー コントロールをインスタンス化する必要があります。次に、test1.htmlファイルに移動します。ドキュメントが読み込まれると、まず Web サーバーがインスタンス化されていないかどうかを確認します。この場合、そのインスタンスを作成し、Web ブラウザーの HTMl ソースを読み取って変数に格納し、コンストラクターresponseに渡します。WebServer

はそのプレフィックスに をhttp://localhost:9999登録するHttpListenerため、このアドレスへのすべてのリクエストは単純な Web サーバーによって処理されます。

次に、そのアドレスに移動します。Web サーバーがリクエストを受信すると_staticContent、Web サーバーのコンストラクターで値が割り当てられた変数の内容を配信します。

サーバーがドキュメントを Web ブラウザーに配信した後、webBrowser1_DocumentCompletedハンドラーがトリガーされます。しかし今回は、すでに Web サーバーのインスタンスがあるため、実行はelseブランチを経由します。注目すべき重要なことは、JavaScript が実行されるのを非同期的に待機し、場所を取得inputして HTML の隠し要素に保存することです。

重要な注意事項: アプリケーションを初めて起動したときは、場所を取得できません。最初にアプリケーションを開いたままにして、カスタム HTTP リスナーを使用できるようにしてから、他の回答で説明した手順を実行する必要があります。閲覧場所は http://localhost:9999です。それを行ったら、アプリケーションを閉じて再度開きます。

それでおしまい。アプリケーションを実行するたびに、メッセージ ボックスに位置座標が表示されます。

クラスForm1ファイル ( 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.net/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();
        }
    }
}

HTML ソース ( test1.html )

<html xmlns="http://www.w3.org/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>
于 2013-02-01T11:59:26.483 に答える
0

これは、WebBrowserコントロールが以前のバージョンの Internet Explorer の互換モードを使用しているために発生する可能性があります。

この機能を使用して、アプリケーションごとに Internet Explorer の既定のエミュレーション モードを設定できますFEATURE_BROWSER_EMULATIONWebBrowserこれは、独自のアプリケーションでコントロールの互換モードを実際に設定する方法です。

構成するには、以下のリンクの指示に従ってください。

インターネット機能コントロール (B..C)

[アップデート]

  1. [インターネット オプション] -> [プライバシー] に移動します
  2. セクションの下で、チェックが外さLocationれていることを確認しますNever allow websites to request your physical location
  3. クリックClear Sites
  4. (アプリケーションではなく) を開きInternet Explorer、地理位置情報スクリプトを含むファイルの URL を参照します。
  5. 関数をトリガーしgetLocation()ます(あなたの場合、Try Itボタンをクリックします)
  6. ブラウザがウィンドウの下部に を含むセキュリティ バーを表示したら、 をyourSite wants to know your physical location.クリックしてOptions for this siteを選択しますAlways allow

それだけです。

于 2013-01-22T09:55:08.660 に答える