コード例 #1
0
        /// <param name="browser"></param>
        /// <exception cref="EnvironmentException">
        /// When there is a problem with either <paramref name="browser"/> or the hosting environment.
        /// </exception>
        public static void Set(Browser browser)
        {
            // In Windows 10 version 1803, the old control-panel-style Default Programs screen has been replaced with a new one inside the Windows 10 settings app.
            // However, the Windows 10 settings app cannot be automated without the user seeing it or interacting with it, so that option is unreliable.
            // Fortunately, someone else has written a better alternative to this app (http://kolbi.cz/blog/?p=396).
            // So for these reasons, this app won't support this or later versions of Windows.
            if (OsInfo.Windows10Version >= 1803)
            {
                throw new EnvironmentException($"This app no longer works in this version of Windows.");
            }

            // This is needed since the control panel applet can crash if you give it an empty browser name
            if (String.IsNullOrWhiteSpace(browser.UniqueApplicationName))
            {
                throw new EnvironmentException($"The given browser's unique application name is blank.");
            }

            using (var desktop = new Desktop("Default Browser Changer"))
            {
                var encodedBrowserName = Uri.EscapeDataString(browser.UniqueApplicationName);
                var desktopProcess     = new DesktopProcess(@"control.exe /name Microsoft.DefaultPrograms /page pageDefaultProgram\pageAdvancedSettings?pszAppName=" + encodedBrowserName, desktop.Name);
                var exitCode           = Wait(() => desktopProcess.GetExitCode()); //TODO: Replace this with WaitForSingleObject
                if (exitCode != 1)                                                 //Control.exe always returns 1 regardless of whether it had valid arguments.
                {
                    throw new Exception("control.exe returned " + exitCode);
                }

                using (new DesktopContext(desktop.Handle))
                {
                    IntPtr window;
                    try
                    {
                        // The window is located by class name rather than caption since the caption is locale-dependent.
                        window = Wait(() => WindowsApi.FindWindow("CabinetWClass" /* Windows Explorer */, IntPtr.Zero));
                    }
                    catch (TimeoutException timeout)
                    {
                        throw new EnvironmentException("The control panel applet didn't open. Try logging out and then logging in again.", timeout);
                    }

                    try
                    {
                        var listViewHandle = Wait(() =>
                        {
                            var matches = FindDescendantsBy(window, className: "SysListView32");
                            var expectedListBoxCount = 1;
                            if (matches.Count > expectedListBoxCount)
                            {
                                throw new Exception($"Found {matches.Count} list box(es), but expected {expectedListBoxCount}.");
                            }

                            return(matches.FirstOrDefault());
                        });

                        var listView = new ListView(listViewHandle);

                        var save = Wait(() =>
                        {
                            var matches = FindDescendantsBy(window, className: "Button");
                            if (matches.Count == 0)
                            {
                                return(default(IntPtr));
                            }

                            var expectedButtonCount = 3; // Select All, Save, Cancel
                            if (matches.Count != expectedButtonCount)
                            {
                                throw new Exception($"Found {matches} button(s), but expected {expectedButtonCount}.");
                            }

                            return(matches[1]);
                        });

                        var browserAssociations = browser.Associations
                                                  .Intersect(new[] { ".htm", ".html", "HTTP", "HTTPS" }, StringComparer.OrdinalIgnoreCase)
                                                  .ToArray();

                        int[] checkboxIndices;
                        try
                        {
                            checkboxIndices = Wait(() =>
                            {
                                var itemIndices =
                                    (
                                        from item in listView.GetListItems().Select((text, index) => new { text, index })
                                        where browserAssociations.Contains(item.text, StringComparer.InvariantCultureIgnoreCase)
                                        select item.index
                                    ).ToArray();

                                if (itemIndices.Length < browserAssociations.Length)
                                {
                                    return(null);
                                }
                                else
                                {
                                    return(itemIndices);
                                }
                            });
                        }
                        catch (TimeoutException timeout)
                        {
                            throw new EnvironmentException($"Didn't find all of the following extensions and protocols: {String.Join(", ", browserAssociations)}.", timeout);
                        }

                        foreach (var i in checkboxIndices)
                        {
                            listView.CheckItem(i);
                        }

                        WindowsApi.SendMessage(save, WindowsApi.BM_CLICK, IntPtr.Zero, IntPtr.Zero);
                    }
                    finally
                    {
                        WindowsApi.SendMessage(window, WindowsApi.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); //Just in case it doesn't close itself
                    }
                }
            }
        }
コード例 #2
0
        /// <param name="browser"></param>
        /// <exception cref="EnvironmentException">
        /// When there is a problem with either <paramref name="browser"/> or the hosting environment.
        /// </exception>
        public static void Set(Browser browser)
        {
            // This is needed since the control panel applet can crash if you give it an empty browser name
            if (String.IsNullOrWhiteSpace(browser.UniqueApplicationName))
            {
                throw new EnvironmentException($"The given browser's unique application name is blank.");
            }

            using (var desktop = new Desktop("Default Browser Changer"))
            {
                var encodedBrowserName = Uri.EscapeDataString(browser.UniqueApplicationName);
                var desktopProcess     = new DesktopProcess(@"control.exe /name Microsoft.DefaultPrograms /page pageDefaultProgram\pageAdvancedSettings?pszAppName=" + encodedBrowserName, desktop.Name);
                var exitCode           = Wait(() => desktopProcess.GetExitCode()); //TODO: Replace this with WaitForSingleObject
                if (exitCode != 1)                                                 //Control.exe always returns 1 regardless of whether it had valid arguments.
                {
                    throw new Exception("control.exe returned " + exitCode);
                }

                using (new DesktopContext(desktop.Handle))
                {
                    IntPtr window;
                    try
                    {
                        window = Wait(() => WindowsApi.FindWindow(IntPtr.Zero, "Set Program Associations"));
                    }
                    catch (TimeoutException timeout)
                    {
                        throw new EnvironmentException("The control panel applet didn't open. Try logging out and then logging in again.", timeout);
                    }

                    try
                    {
                        var listViewHandle = Wait(() => FindDescendantBy(window, className: "SysListView32"));
                        var listView       = new ListView(listViewHandle);
                        var save           = Wait(() => FindDescendantBy(window, text: "Save"));

                        var browserAssociations = browser.Associations
                                                  .Intersect(new[] { ".htm", ".html", "HTTP", "HTTPS" }, StringComparer.OrdinalIgnoreCase)
                                                  .ToArray();

                        int[] checkboxIndices;
                        try
                        {
                            checkboxIndices = Wait(() =>
                            {
                                var itemIndices =
                                    (
                                        from item in listView.GetListItems().Select((text, index) => new { text, index })
                                        where browserAssociations.Contains(item.text, StringComparer.InvariantCultureIgnoreCase)
                                        select item.index
                                    ).ToArray();

                                if (itemIndices.Length < browserAssociations.Length)
                                {
                                    return(null);
                                }
                                else
                                {
                                    return(itemIndices);
                                }
                            });
                        }
                        catch (TimeoutException timeout)
                        {
                            throw new EnvironmentException($"Didn't find all of the following extensions and protocols: {String.Join(", ", browserAssociations)}.", timeout);
                        }

                        foreach (var i in checkboxIndices)
                        {
                            listView.CheckItem(i);
                        }

                        WindowsApi.SendMessage(save, WindowsApi.BM_CLICK, IntPtr.Zero, IntPtr.Zero);
                    }
                    finally
                    {
                        WindowsApi.SendMessage(window, WindowsApi.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); //Just in case it doesn't close itself
                    }
                }
            }
        }