9

I have a method from an existing .NET Framework project that gets the path to the default browser in Windows from the Registry and launches it with a Process call:

string browser = "";
RegistryKey regKey = null;

try
{
    regKey = Registry.ClassesRoot.OpenSubKey("HTTP\\shell\\open\\command", false);
    browser = regKey.GetValue(null).ToString().Replace("" + (char)34, "");
    if (!browser.EndsWith(".exe"))
        browser = browser.Substring(0, browser.LastIndexOf(".exe") + 4);
}
finally
{
    if (regKey != null)
        regKey.Close();
}

ProcessStartInfo info = new ProcessStartInfo(browser);
info.Arguments = "\"" + url + "\"";
Process.Start(info);

This project is trying to get setup to go cross-platform, so I'm porting it to .NET Standard (1.2). The problem is that I'm not sure what the .NET Standard equivalents are to RegistryKey and Process (and ProcessStartInfo). Of course, being for other platforms, there may not be a registry or any concept of "processes" on that system. So is there a way to achieve the above functionality in .NET Standard? (Or perhaps this is an X-Y Problem and I'm going about it all wrong?)

Abion47
  • 22,211
  • 4
  • 65
  • 88
  • I'd say that "get path to default browser then launch it" is just not portable. – Evk May 24 '17 at 07:46
  • 2
    FYI, on Windows at least, you can directly go to an URL in the default browser by doing just this: `Process.Start("https://www.google.com");`. No need to go to the registry for this :) – Lucas Trzesniewski May 24 '17 at 07:54
  • @Evk I'm mainly concerned about the "main" desktop platforms right now (Windows, Mac OS, maybe the more popular flavors of Linux), so I'm hoping that it will be portable enough and figure out an alternate approach if I need to later on. – Abion47 May 24 '17 at 08:02
  • @LucasTrzesniewski That's a fancy trick. I wonder if that approach is cross-platform as well. – Abion47 May 24 '17 at 08:02

2 Answers2

10

Registry is only available in .NET Standard 1.3 using the Microsoft.Win32.Registry NuGet package. So you cannot target 1.2 if you want to use the registry.

Similarly, System.Diagnostics.Process is available for .NET Standard 1.3 using the NuGet package System.Diagnostics.Process (for .NET Standard 2.0, no separate NuGet package is required to access it).

For getting the "default browser", there is not full cross-platform solution since you'd need to integrate with whatever desktop solution the user is using - e.g. MacOS, KDE, GNOME, Ubuntu Unity etc.

Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • The current project targets .NET Framework 4.5.2, and it's my understanding that .NET Standard 1.2 is the "newest" version supported by programs run under that version. – Abion47 May 24 '17 at 07:59
  • The reason for .NET Framework 4.5.2 is that this project has some clients that run it on Windows 7, so I'd prefer not to tell those people that they can suddenly no longer use this program. – Abion47 May 24 '17 at 08:04
  • Though I'm reading the version requirements for the different versions of .NET Framework, and it says that 4.6 is supported by Windows 7 as well (albeit with some additional installs), so I'm not sure where I got the impression that 4.5.2 was the latest version that I could use. – Abion47 May 24 '17 at 08:07
  • Yes that is a problem, the other solution would be to multi target - build the library for both net452 and netstandard1.3. You'd then only reference the NuGet packages for netstandard and have a NuGet package / project you can use in both .net core and .net framework applications. – Martin Ullrich May 24 '17 at 08:32
  • I... have no idea how to do that. :P – Abion47 May 24 '17 at 09:35
  • 1
    e.g. like https://stackoverflow.com/questions/42747977/how-do-you-multi-target-a-net-core-class-library-with-csproj – Martin Ullrich May 24 '17 at 09:43
  • Just out of idle curiosity, I'm going to set up a Windows 7 virtual machine and see if it can still run my program under 4.6.2. – Abion47 May 24 '17 at 22:04
1

For registry at least there is a solution available in .NET Standard, but it is only compatible from version 1.3:

The Windows registry is a self-contained component that will be provided as a separate NuGet package (e.g. Microsoft.Win32.Registry). You’ll be able to consume it from .NET Core, but it will only work on Windows. Calling registry APIs from any other OS will result in PlatformNotSupportedException. You’re expected to guard your calls appropriately or making sure your code will only ever run on Windows. We’re considering improving our tooling to help you with detecting these cases.

So include the appropriate NuGet package and you should be fine for the Registry class.

System.Diagnostics.Process is supported in .NET Standard 1.3, so that should be fine too if you can migrate.

That said, I don't think you will get this part of the program working this way, for Windows, yes, but for other platform you might need an entire different approach.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325