1

I am trying to open a web page using the default browser when someone hits an API endpoint.

I have this working on my local test machine:

    [HttpGet("Http/{classId}")]
    public void OpenWebLink(Guid classId)
    {
        string target = "http://astrolab.meeting.trl.edu/class/details.aspx?classId=" + classId;
        System.Diagnostics.Process.Start("C:\\Program Files\\Mozilla Firefox\\firefox.exe", target);
    }

But when I publish to a server that has IIS, it can't find firefox.exe

The problem is, I had to put the full path to firefox just to get it to work on my machine. If I didn't include the path like that I'd get this error:

System.Diagnostics.Process.Start Win32Exception: 'The system cannot find the file specified.'

I also tried this:

    [HttpGet("Http")]
    public void OpenWebLink(Guid classId)
    {
        try
        {

            var ps = new ProcessStartInfo("http://astrolab.meeting.trl.edu/class/details.aspx?classId=" + classId;)
            {
                Verb = "open"
            };
        Process.Start(ps);
        }
        catch (Win32Exception w32Ex) 
        {
            throw w32Ex;
        }
    }

But it still fails when I hit the endpoint on the IIS server with this:

System.ComponentModel.Win32Exception (2): The system cannot find the file specified.

Is there a way to set it up so that it will find the default browser on any machine?

Thanks!

SkyeBoniwell
  • 6,345
  • 12
  • 81
  • 185
  • 2
    Instead of specifying the browser, just specify the URL (see https://stackoverflow.com/questions/4580263/how-to-open-in-default-browser-in-c-sharp) – Gus Nov 09 '20 at 18:01
  • @Gus Hi! I did try that, but unfortunately it just returns a `Win32Exception` stating that it can't find the file specified. – SkyeBoniwell Nov 09 '20 at 18:02

2 Answers2

2

Either use ShellExecute to launch your url (the more correct way), or pipe it through explorer (the lazier, less portable way).

Process.Start(new()
{
    UseShellExecute = true,
    FileName = "http://google.ca",
});

Process.Start("explorer.exe", "http://google.ca");
Blindy
  • 65,249
  • 10
  • 91
  • 131
  • thank you, so I would use `UseShellExecute` if I wanted it to work on most machines using that machines default browser? When using `UseShellExecute` do I exclude the name of the browser in `Process.Start` ? thanks – SkyeBoniwell Nov 09 '20 at 18:20
  • Hi when I tried this, Visual Studio is indicating an error here: `Process.Start(new()`, ... the keyword `new` is underlined and says `The feature 'target-typed object creation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.` – SkyeBoniwell Nov 09 '20 at 18:23
  • That is correct, yes. Are you asking how to use C# 9? Or how to instantiate a class in C# 8 or below? – Blindy Nov 09 '20 at 18:51
  • I am using .net 3.1 so I hope it's whatever c# version comes with that. I can try to upgrade if it helps thanks – SkyeBoniwell Nov 09 '20 at 19:06
  • You can use `Process.Start(new ProcessStartInfo { ... };` in C#8. I recommend reading about classes if that was indeed your question. – Blindy Nov 09 '20 at 19:10
  • So I tried it, you can see the new code above. And it still fails when I publish it to my IIS server. It works locally though. Maybe that code is trying to open the browser on the IIS server and not the client machine? – SkyeBoniwell Nov 09 '20 at 19:24
  • 1
    Yes, of course, it opens the window on the machine on which it runs. – Blindy Nov 09 '20 at 19:26
  • thanks, I think that's where my logic failed. I was thinking that it would open the browser on the client machine and not the server :/ – SkyeBoniwell Nov 09 '20 at 20:09
  • 1
    Can you imagine the security risks if any web page could start executing random programs on your computer? That will never happen! – Blindy Nov 09 '20 at 20:22
  • That solution only works if the end-user is on Windows. @Blindy you have to explain this in your answer. – adamency Dec 05 '22 at 12:03
2

It's as if dotnet developers are unaware of other operating systems besides Windows...

@Blindy's answer only works on Windows, but nowhere did they indicate this. And even if @SkyeBoniwell's question mentions IIS which implies Windows, neither the title of the question, nor the body, nor the tags explicitly mention Windows. As such, keeping in mind stackoverflow answers are meant to be used by everyone and not only the OP of a question, a correct answer to this thread should theoretically be os-agnostic. In practice, it should take into account as many operating systems as possible, i.e. at the very least the main three ones.

Here is a solution that works for 99% of end-user systems:

    public static void OpenBrowser(string url)
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
        Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            Process.Start("xdg-open", url);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
        {
            Process.Start("open", url);
        }
        else
        {
            // throw 
        }
    }

taken from here

adamency
  • 682
  • 6
  • 13