Question

I've been trying for a couple weeks now to run a non-elevated web browser from an elevated process, I have tried various things, duplicating the explorer token, using the WinSafer Apis mentioned here and various other techniques that all failed. Finally I decided to use Microsoft's suggestion of using the Task Scheduler to run the application.

I used the Task Scheduler Managed Wrapper, at first I tried running explorer.exe and passing the url as a command but that did not work so I created a dummy executable that'll launch the site using Process.Start.

Here is how I create the task:

public static void LaunchWin8BrowserThroughTaskScheduler(string sURL)
        {
            String RunAsUserExecPath = AppDomain.CurrentDomain.BaseDirectory + "URLLaunch.exe";

            String Command = string.Format("-w \"{0}\"", sURL);

            using (TaskService ts = new TaskService())
            {
                TaskDefinition td = ts.NewTask();
                td.RegistrationInfo.Description = "URL Launch";
                td.Principal.LogonType = TaskLogonType.InteractiveToken;
                TimeTrigger trigger = new TimeTrigger(DateTime.Now.AddSeconds(2))
                                          {
                                              Enabled = true,
                                              EndBoundary = DateTime.Now.AddSeconds(10)
                                          };


                td.Triggers.Add(trigger);

                td.Actions.Add(new ExecAction( RunAsUserExecPath, Command, null));
                td.Settings.StartWhenAvailable = true;
                //Delete the task after 30 secs
                td.Settings.DeleteExpiredTaskAfter = new TimeSpan(0,0,0,30);
                ts.RootFolder.RegisterTaskDefinition("URL Launch", td, TaskCreation.CreateOrUpdate, null, null, TaskLogonType.InteractiveToken);

            }

    }

and this is the code to my dummy executable:

static void Main(string[] args)
        {
            if(args.Length<=1)
                return;

            string sCmd = args[0];
            string sArg = args[1];

            if(string.IsNullOrEmpty(sCmd)||string.IsNullOrEmpty(sArg))
                return;

            switch (sCmd)
            {
                case "-w":
                    {
                        Process prs = Process.Start(sArg);                        
                    }
                    break;
            }


        }

This method is working, and the browser is indeed launched non-elevated and I was able to confirm that by checking the Elevated column in Windows 8's task manager.

The only nuance here is that the browser is not launched as the top most window, it is running in the background and I think its got to do with the fact that its being run through task scheduler.

This is causing me problems especially with Modern UI browsers because Windows does not switch to them when a page is launched. I can see that the page has been successfully launched in Chrome, for example, while running in Windows 8 mode, but the fact that it does not switch to the browser just defies the whole purpose of this workaround.

I thought about using SetForegroundWindow but sadly running a URL like the example above or through explorer.exe, Process.Start returns null.

I was wondering if someone can help me fix this and be able to run the browser in foreground.

Regards

Was it helpful?

Solution

I've been able to solve the issue with a very simplistic method.

Just write a shortcut file to somewhere like the TempFolder and execute it through explorer.exe likes so:

public static void GoURL(string url)
{
 string sysPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
                string ExplorerPath = Path.Combine(Directory.GetParent(sysPath).FullName,
                                                      "explorer.exe");
                string TempDir = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
                string shortcutPath = Path.Combine(TempDir, "Mylink.url");
                urlShortcutToTemp(url, shortcutPath);
                System.Diagnostics.Process.Start(ExplorerPath, shortcutPath);
}

private static void urlShortcutToTemp(string linkUrl, string shortcutPath)
        {
            using (StreamWriter writer = new StreamWriter(shortcutPath))
            {
                writer.WriteLine("[InternetShortcut]");
                writer.WriteLine("URL=" + linkUrl);
                writer.Flush();
            }
        }

The same solution can be applied to executables with lnk shortcuts.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top