19

I'm developing an anti-theft software to get computers exact location. Notebooks with built-in gps are very rare in my country so I have to use HTML5 Geolocation in my application.

For Internet Explorer 9+, there is a registry key that you can add urls to allow a url without needing user verification. If you add an REG_DWORDvalue named domain.com under HKCU\Software\Microsoft\Internet Explorer\Geolocation\HostConsent path browser will allow geolocation request automatically. However I can't run Internet Explorer hidden so thats not working for me since thief shouldn't realize and see what's going on.

  • I need to run Internet Explorer hidden somehow
  • ...or I need to embed webkit or something to my application but I don't know how can I use it or how can I allow this request programmatically.

I prefer second way because Internet Explorer is now terminated by Microsoft and I think next version will have different structure.

How can I embed and use Webkit or GeckoFX to my application? How can I allow a geolocation request programmatically in this application?

Batuhan
  • 270
  • 3
  • 16
  • You really should NOT use HTML 5 on server. You're crossing boundaries with no advantage. I understand what you're going after, but you can reverse-engineer this. Consider using C# Google Maps instead: http://www.codeproject.com/Tips/889136/Csharp-Google-Maps-in-WinForm-with-WebBrowser-and – Dave Alperovich May 19 '15 at 02:34
  • @DaveAlperovich Actually I want to use HTML5 on the client side. Client will visit a page [like this one](http://html5demos.com/geo) and send returned infomation to server. – Batuhan May 25 '15 at 08:10
  • 1
    When I imagine security software, I imagine a desktop (winforms/WPF app). Self-encapsulated native application using native drivers to detect if a user has failed to authenticate... Maybe sending it's own authentication challenges. Should user fail them, request a geolocation service (like GMAP). Such an application can run as Deamon with Admin privileges, making it very hard for an invader to indentify and even harder to disable. Dependance on a secondary app like a browser would make your security app less powerful (browsers are disconnected from OS) and more fragile. – Dave Alperovich May 25 '15 at 08:19

4 Answers4

8

Relying on a hidden browser is a risky solution, and it will inevitably break at some point in the future.

Instead you want to build geolocation functionality into your own application. The two major sources of location info are your IP address (which you then feed into any of the GeoIP providers) and cellular/Wi-Fi stations visible (which you feed into Google geolocation API).

Community
  • 1
  • 1
Michael Diomin
  • 520
  • 3
  • 13
  • Thanks! That Google API is what I need. Do you know how can I get required wifi informations like signal strength, signal to noise ratio, channel in my C# application? Are there any libraries for this? – Batuhan Mar 25 '15 at 21:33
  • @Batuhan: A quick search for "C# wifi signal strength" returns [this](http://stackoverflow.com/questions/18758097/getting-wifi-signal-strength). I don't suppose the other APIs will be any more difficult to find. – voithos May 24 '15 at 00:22
4

Have a look at the GeoCoordinateWatcher class which is defined in the System.Device assembly

The GeoCoordinateWatcher class supplies coordinate-based location data from the current location provider. The current location provider is prioritized as the highest on the computer, based on a number of factors, such as the age and accuracy of the data from all providers, the accuracy requested by location applications, and the power consumption and performance impact associated with the location provider. The current location provider might change over time, for instance, when a GPS device loses its satellite signal indoors and a Wi-Fi triangulation provider becomes the most accurate provider on the computer.

Usage example :

static void Main(string[] args)
{
    GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();

    watcher.StatusChanged += (sender, e) =>
    {
        Console.WriteLine("new Status : {0}", e.Status);
    };

    watcher.PositionChanged += (sender, e) =>
    {
        Console.WriteLine("position changed. Location : {0}, Timestamp : {1}",
            e.Position.Location, e.Position.Timestamp);
    };

    if(!watcher.TryStart(false, TimeSpan.FromMilliseconds(5000)))
    {
         throw new Exception("Can't access location"); 
    }

    Console.ReadLine();
}

I think this class relies on the same mechanism than the one use by Internet Explorer.

When you will use it, you will have an icon in your system notification tray telling that location has recently been accessed.

enter image description here

You will also have an entry added on windows logs.

Cyril Durand
  • 14,153
  • 5
  • 45
  • 54
  • Its a native and elegant way to do the job, thank you! But I think Windows won't allow me to turn off that notifications because of its privacy policy. I'm looking for more secrecy for this, after all this is an anti-theft software and I don't want to say "Hi thief, I know where you are!" :) – Batuhan May 25 '15 at 08:49
2

If you are deploying to a modern version of Windows, you could use the library native to .NET System.Device.Location which allows you to obtain device location information.

Here is a link on MSDN for how to use it GeoCoordinate Class

If using XAML, you can also try this method. Detect Users Location using XAML

Kraang Prime
  • 8,620
  • 8
  • 50
  • 107
1

You can embed a webkit browser into your application by using PhantomJS. PhantomJS is a headless browser and can be added to your application through searching NuGet or the NuGet command line PM> Install-Package PhantomJS. Once PhantomJS has been added to your project, you'll want to build a file to control phantom something like:

 public string PhantomJson(string phantomControlFile, params string[] arguments)
        {
            string returnJsonString = String.Empty;

            if (!String.IsNullOrEmpty(URL))
            {
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    CreateNoWindow = true,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    FileName = Path.Combine(PhantomExecutionPath, "phantomjs.exe"),
                    UseShellExecute = false,
                    WorkingDirectory = PhantomExecutionPath,
                    Arguments = @"--proxy-type=none --ignore-ssl-errors=true {1} ""{0}"" {2}".FormatWith(URL, phantomControlFile, 
                        arguments.Any() ? String.Join(" ", arguments) : String.Empty)
                };

                StringBuilder receivedData = new StringBuilder();
                using (Process p = Process.Start(startInfo))
                {
                    p.OutputDataReceived += (o, e) =>
                    {
                        if (e.Data != null && e.Data != "failed")
                        {
                            //returnJsonString = e.Data;
                            receivedData.AppendLine(e.Data);
                        }
                    };
                    p.BeginOutputReadLine();
                    p.WaitForExit();
                }
                returnJsonString = receivedData.ToString();

                if (!String.IsNullOrEmpty(returnJsonString))
                {
                    return returnJsonString;
                }
                else
                {
                    throw new ArgumentNullException("Value returned null. Unable to retrieve data from server");
                }
            }
            else
            {
                throw new ArgumentNullException("Url cannot be null");
            }
        }

Then you'll want to build a control file to tell phantomjs where to go; something like:

var args, myurl, page, phantomExit, renderPage, system;

system = require("system");
args = system.args;
page = null;
myurl = args[1];

phantomExit = function(exitCode) { // this is needed as there are time out issues when it tries to exit.
  if (page) {
    page.close();
  }
  return setTimeout(function() {
    return phantom.exit(exitCode);
  }, 0);
};

renderPage = function(url) {
  page = require("webpage").create();
    return page.open(url, function(status) {
      if (status === 'success') {
         // Process Page and console.log out the values
         return phatomExit(0);
      } else {
         console.log("failed");
         return phantomExit(1);
      }
     });
   };
  renderPage(myurl);
rogergarrison
  • 1,004
  • 6
  • 7