WinForms 应用程序中的地理位置
Posted
技术标签:
【中文标题】WinForms 应用程序中的地理位置【英文标题】:Geolocation in WinForms application 【发布时间】:2013-05-23 14:39:34 【问题描述】:我想创建一个 WinForms 应用程序,它可以像 Web 浏览器使用 javascript 函数 navigator.geolocation.getCurrentPosition(showPosition);
一样检测位置
有没有办法直接在 WinForms 中做到这一点?
我认为我可以使用 WebBrowser 控件来执行此操作,但我认为这不支持地理定位(除非有人知道?)
显然 Gecko 浏览器确实支持地理定位,但这对我来说不是一个选项,因为客户端可能安装了不同的 firefox 版本。
【问题讨论】:
可能重复:***.com/questions/5591457/… @Anthony - 不完全是重复的,因为该问题仅是来自 IP 的地理位置查找。如果通过加密狗连接,网络浏览器可以使用其他传感器来检测位置,例如 Wi-Fi 信号和 A-GPS 好点,留下链接供其他人参考 【参考方案1】:你应该使用Geckofx
您还需要确保 geckofx 版本与正确的 xulrunner/firefox 版本完全匹配。
GeoLocation 在 geckofx 中还没有很好的 C# 包装类,但您可以使用 xpcom C# 互操作来访问它。
var instance = Xpcom.CreateInstance<nsIGeolocationProvider>("@mozilla.org/geolocation/provider;1");
【讨论】:
谢谢,但我在帖子中提到我不能使用这个组件,因为它是用于商业产品的,所以我无法指定任何目标机器上的 xulrunner/firefox 版本。 您可以将所需版本的 xulrunner/firefox 与您的应用程序捆绑在一起。我使用我正在处理的应用程序执行此操作,所需的文件总大小约为 20MB,可以为安装程序压缩。【参考方案2】:我没用过,但微软有一个Windows.Devices.Geolocation API,虽然它适用于 Windows 8。
对于 Windows 7,他们似乎有一个 Sensor API,带有一些示例代码 here。
【讨论】:
不幸的是,windows 7 传感器 API 仅在安装了传感器并且我能找到的唯一传感器驱动程序是适用于 Windows 的 Geosense 时才有效。然而,这似乎已被淘汰,我找不到有效的下载。【参考方案3】:感谢Alex Filipovici在这个问题上给出的答案:C# desktop application doesn't share my physical location
下面是转换成VB的代码:
WebServer 类:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Net
Imports System.Text
Imports System.Threading
Public Class WebServer
Private ReadOnly _listener As New HttpListener()
Private Shared _staticContent As String
Public Sub New(ByVal prefixes() As String, ByVal content As String)
_staticContent = content
For Each s As String In prefixes
_listener.Prefixes.Add(s)
Next s
_listener.Start()
End Sub
Public Sub New(ByVal content As String, ByVal ParamArray prefixes() As String)
Me.New(prefixes, content)
End Sub
Public Sub Run()
ThreadPool.QueueUserWorkItem(Sub(o)
Try
Do While _listener.IsListening
ThreadPool.QueueUserWorkItem(Sub(c)
Dim ctx = TryCast(c, HttpListenerContext)
Try
Dim buf() As Byte = Encoding.UTF8.GetBytes(_staticContent)
ctx.Response.ContentLength64 = buf.Length
ctx.Response.OutputStream.Write(buf, 0, buf.Length)
Catch
Finally
ctx.Response.OutputStream.Close()
End Try
End Sub, _listener.GetContext())
Loop
Catch
End Try
End Sub)
End Sub
Public Sub [Stop]()
_listener.Stop()
_listener.Close()
End Sub
End Class
表格代码:
Imports System.Reflection
Imports System.Net
Imports System.Threading
Imports System.Text
Public Class Form1
Dim _ws As WebServer
Dim _webbrowser1 As WebBrowser
Public Sub New()
InitializeComponent()
_webBrowser1 = New WebBrowser()
_webBrowser1.Visible = False
_webBrowser1.ScriptErrorsSuppressed = True
Dim location = System.Reflection.Assembly.GetExecutingAssembly().Location
_webBrowser1.Navigate(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) & "\test1.html")
AddHandler _webBrowser1.DocumentCompleted, AddressOf webBrowser1_DocumentCompleted
End Sub
Async Sub webBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
If _ws Is Nothing Then
Dim html = _webBrowser1.Document.GetElementsByTagName("html")
Dim response = html(0).OuterHtml
_ws = New WebServer(response, "http://localhost:9999/")
_ws.Run()
_webBrowser1.Navigate("http://localhost:9999/")
Else
Dim latitude As String = ""
Dim longitude As String = ""
Await Task.Factory.StartNew(Sub()
While String.IsNullOrEmpty(latitude)
System.Threading.Thread.Sleep(1000)
If Me.InvokeRequired Then
Me.Invoke(DirectCast(Sub()
Dim latitudeEl = _webbrowser1.Document.GetElementById("latitude")
Dim longitudeEl = _webbrowser1.Document.GetElementById("longitude")
latitude = latitudeEl.GetAttribute("value")
longitude = longitudeEl.GetAttribute("value")
End Sub, MethodInvoker))
End If
End While
End Sub)
txtLocation.Text = String.Format("0,1", latitude, longitude)
End If
End Sub
End Class
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>
【讨论】:
以上是关于WinForms 应用程序中的地理位置的主要内容,如果未能解决你的问题,请参考以下文章
为啥 WPF 中的鼠标位置不正确,而缩放桌面上的 Winforms 则不正确?
RichTextBox C# 设置插入符号位置 winforms
为啥我的 WinForms 上下文菜单没有出现在鼠标所在的位置?