0

I've got a F# application, where I need to open an URL in the user's default browser. This is all well and good, and is handled just fine by the following method:

member this.openUrl (url:Uri) =
    ignore (System.Diagnostics.Process.Start(url.ToString()))

Upon opening the URL, however, the browser takes focus, taking the user away from my program. This is sub-optimal, as it's likely that the user would like to open several pages in quick succession. In that case, the browser getting focus, making the user have to manually switch back to my application. This disturbs the intended workflow of my application.

Is there a way to prevent the default browser from becoming active when asking it to open an URL?

You can assume that I'll add an option for disabling this behavior, if you're worried about the user experience.

Sebastian Paaske Tørholm
  • 49,493
  • 11
  • 100
  • 118
  • I suspect you're going to have to use PInvoke and set the focus back to the current process. Search for "activate process" or "focus process." – Daniel Aug 17 '12 at 14:59
  • Or use the `System.Diagnostics.Process.Start(ProcessStartInfo)` overload and use `WindowStyle` to open it as minimzed? – Mark Pattison Aug 17 '12 at 15:02
  • @MarkPattison Trying that still gave focus to Chrome. – Sebastian Paaske Tørholm Aug 17 '12 at 15:08
  • 6
    This has little to do with F# except for the fact you're coding it in that language. I am certain the behavior would be exactly the same in C# or VB.Net. – Onorio Catenacci Aug 17 '12 at 16:51
  • @OnorioCatenacci: I suppose so. – Sebastian Paaske Tørholm Aug 17 '12 at 21:39
  • I'm quite confused about the downvotes. Anyone got any comments for what makes this a poor question? – Sebastian Paaske Tørholm Aug 17 '12 at 21:41
  • A shot in the dark: have you tried taking the focus away from your window and then giving it back, just after opening the URL? (or maybe minimize and restore the current window) From my experience, if you open a program and immediatly clicks another window, the program opens behind that window. If done quick enough it will likely not disturb the user despite the visual "glitch". – mgibsonbr Aug 26 '12 at 14:54
  • 1
    Ultimately, how a browser (IE, Ch, FF, etc.) behave with regard to activation/focus/etc. is the browser's business. Why don't you host a browser (IE for example) in your own form(s)? – Simon Mourier Aug 26 '12 at 17:32

2 Answers2

1

AppActive does what you need.

Module Module1

    Sub Main()
        Dim processId As Integer = System.Diagnostics.Process.GetCurrentProcess().Id
        Console.WriteLine("Starting Google")
        System.Diagnostics.Process.Start("www.google.com")
        System.Threading.Thread.Sleep(1000)
        Console.WriteLine("Get Focus Back on Process {0}", processId)
        Microsoft.VisualBasic.Interaction.AppActivate(processId)
        Console.Write("Press any key")
        Console.ReadKey()
    End Sub

End Module

Dont forget to add a reference to Microsoft.VisualBasic in F#

AppActivate http://msdn.microsoft.com/en-us/library/x9784w8e.aspx

Many user are facing problems with AppActivate when running Console programs from Command Line. The answer to this follows (from AppActivate documentantion):

You can use AppActivate only with processes that own windows. Most console applications do not own windows, which means that they do not appear in the list of processes that AppActivate searches. When running from a console application, the system creates a separate process to run the application and returns the output to the console process. Consequently, when you request the current process ID, you get the process ID of this separate process, rather than the console application's process ID.

athoik
  • 363
  • 4
  • 8
0

you should probably do something like this
this code is in c# but you can easily port it to f#

AutomationElement desktop = AutomationElement.RootElement;
AutomationElement mainForm = null;
do
{
    mainForm = desktop.FindFirst(TreeScope.Children,
        new PropertyCondition(AutomationElement.NameProperty, "MDSClientForm"));
    Thread.Sleep(100);
}
while (mainForm == null);
mainForm.setFocus()

this uses the automation UI framework by Microsoft

Parv Sharma
  • 12,581
  • 4
  • 48
  • 80