示例#1
0
        /// <summary>
        /// Registers a URL protocol in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="urlProtocol">The URL protocol to register.</param>
        /// <param name="machineWide">Register the URL protocol machine-wide instead of just for the current user.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="accessPoint">Indicates that the handler shall become the default handler for the protocol.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="urlProtocol"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.UrlProtocol urlProtocol, bool machineWide, [NotNull] ITaskHandler handler, bool accessPoint = false)
        {
            #region Sanity checks
            if (urlProtocol == null)
            {
                throw new ArgumentNullException(nameof(urlProtocol));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            if (string.IsNullOrEmpty(urlProtocol.ID))
            {
                throw new InvalidDataException("Missing ID");
            }

            var hive = machineWide ? Registry.LocalMachine : Registry.CurrentUser;

            if (urlProtocol.KnownPrefixes.Count == 0)
            {
                if (accessPoint)
                { // Can only be registered invasively by registering protocol ProgID (will replace existing and become default)
                    using (var progIDKey = hive.CreateSubKeyChecked(FileType.RegKeyClasses + @"\" + urlProtocol.ID))
                        FileType.RegisterVerbCapability(progIDKey, target, urlProtocol, machineWide, handler);
                }
            }
            else
            { // Can be registered non-invasively by registering custom ProgID (without becoming default)
                using (var progIDKey = hive.CreateSubKeyChecked(FileType.RegKeyClasses + @"\" + FileType.RegKeyPrefix + urlProtocol.ID))
                {
                    // Add flag to remember whether created for capability or access point
                    progIDKey.SetValue(accessPoint ? FileType.PurposeFlagAccessPoint : FileType.PurposeFlagCapability, "");

                    FileType.RegisterVerbCapability(progIDKey, target, urlProtocol, machineWide, handler);
                }

                if (accessPoint)
                {
                    foreach (var prefix in urlProtocol.KnownPrefixes)
                    {
                        if (WindowsUtils.IsWindowsVista && !machineWide)
                        {
                            using (var someKey = Registry.CurrentUser.CreateSubKeyChecked(RegKeyUserVistaUrlAssoc + @"\" + prefix.Value + @"\UserChoice"))
                                someKey.SetValue("ProgID", FileType.RegKeyPrefix + urlProtocol.ID);
                        }
                        else
                        {
                            // Setting default invasively by registering protocol ProgID
                            using (var progIDKey = hive.CreateSubKeyChecked(FileType.RegKeyClasses + @"\" + prefix.Value))
                                FileType.RegisterVerbCapability(progIDKey, target, urlProtocol, machineWide, handler);
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Unregisters a URL protocol in the current system.
        /// </summary>
        /// <param name="urlProtocol">The URL protocol to remove.</param>
        /// <param name="machineWide">Unregister the URL protocol machine-wide instead of just for the current user.</param>
        /// <param name="accessPoint">Indicates that the handler was the default handler for the protocol.</param>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="urlProtocol"/> is invalid.</exception>
        public static void Unregister(Store.Model.Capabilities.UrlProtocol urlProtocol, bool machineWide, bool accessPoint = false)
        {
            #region Sanity checks
            if (urlProtocol == null)
            {
                throw new ArgumentNullException("urlProtocol");
            }
            #endregion

            if (string.IsNullOrEmpty(urlProtocol.ID))
            {
                throw new InvalidDataException("Missing ID");
            }

            // TODO: Implement
        }
示例#3
0
        /// <summary>
        /// Registers a URL protocol in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="urlProtocol">The URL protocol to register.</param>
        /// <param name="machineWide">Register the URL protocol machine-wide instead of just for the current user.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="accessPoint">Indicates that the handler shall become the default handler for the protocol.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem.</exception>
        /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="urlProtocol"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.UrlProtocol urlProtocol, bool machineWide, [NotNull] ITaskHandler handler, bool accessPoint = false)
        {
            #region Sanity checks
            if (urlProtocol == null)
            {
                throw new ArgumentNullException("urlProtocol");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            #endregion

            if (string.IsNullOrEmpty(urlProtocol.ID))
            {
                throw new InvalidDataException("Missing ID");
            }

            // TODO: Implement
        }
示例#4
0
        /// <summary>
        /// Registers an application as a candidate for a default program for some service in the current system. This can only be applied machine-wide, not per user.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="defaultProgram">The default program information to be registered.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="accessPoint">Indicates that the program should be set as the current default for the service it provides.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="defaultProgram"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.DefaultProgram defaultProgram, [NotNull] ITaskHandler handler, bool accessPoint = false)
        {
            #region Sanity checks
            if (defaultProgram == null)
            {
                throw new ArgumentNullException("defaultProgram");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            #endregion

            if (string.IsNullOrEmpty(defaultProgram.ID))
            {
                throw new InvalidDataException("Missing ID");
            }
            if (string.IsNullOrEmpty(defaultProgram.Service))
            {
                throw new InvalidDataException("Missing Service");
            }

            using (var serviceKey = Registry.LocalMachine.CreateSubKeyChecked(RegKeyMachineClients + @"\" + defaultProgram.Service))
            {
                using (var appKey = serviceKey.CreateSubKeyChecked(defaultProgram.ID))
                {
                    // Add flag to remember whether created for capability or access point
                    appKey.SetValue(accessPoint ? FileType.PurposeFlagAccessPoint : FileType.PurposeFlagCapability, "");

                    appKey.SetValue("", target.Feed.Name);

                    FileType.RegisterVerbCapability(appKey, target, defaultProgram, true, handler);

                    // Set callbacks for Windows SPAD
                    using (var installInfoKey = appKey.CreateSubKeyChecked(RegSubKeyInstallInfo))
                    {
                        string exePath = Path.Combine(Locations.InstallBase, "0install-win.exe").EscapeArgument();
                        installInfoKey.SetValue(RegValueReinstallCommand, exePath + " integrate-app --machine --batch --add=defaults " + target.Uri.ToStringRfc().EscapeArgument());
                        installInfoKey.SetValue(RegValueShowIconsCommand, exePath + " integrate-app --machine --batch --add=icons " + target.Uri.ToStringRfc().EscapeArgument());
                        installInfoKey.SetValue(RegValueHideIconsCommand, exePath + " integrate-app --machine --batch --remove=icons " + target.Uri.ToStringRfc().EscapeArgument());
                        installInfoKey.SetValue(RegValueIconsVisible, 0, RegistryValueKind.DWord);
                    }

                    if (defaultProgram.Service == Store.Model.Capabilities.DefaultProgram.ServiceMail)
                    {
                        var mailToProtocol = new Store.Model.Capabilities.UrlProtocol {
                            Verbs = { new Verb {
                                          Name = Verb.NameOpen
                                      } }
                        };
                        using (var mailToKey = appKey.CreateSubKeyChecked(@"Protocols\mailto"))
                            FileType.RegisterVerbCapability(mailToKey, target, mailToProtocol, true, handler);
                    }
                }

                if (accessPoint)
                {
                    serviceKey.SetValue("", defaultProgram.ID);
                }
            }
        }
示例#5
0
        /// <summary>
        /// Registers an application as a candidate for a default program for some service in the current system. This can only be applied machine-wide, not per user.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="defaultProgram">The default program information to be registered.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="accessPoint">Indicates that the program should be set as the current default for the service it provides.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="defaultProgram"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.DefaultProgram defaultProgram, [NotNull] ITaskHandler handler, bool accessPoint = false)
        {
            #region Sanity checks
            if (defaultProgram == null) throw new ArgumentNullException(nameof(defaultProgram));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            if (string.IsNullOrEmpty(defaultProgram.ID)) throw new InvalidDataException("Missing ID");
            if (string.IsNullOrEmpty(defaultProgram.Service)) throw new InvalidDataException("Missing Service");

            using (var serviceKey = Registry.LocalMachine.CreateSubKeyChecked(RegKeyMachineClients + @"\" + defaultProgram.Service))
            {
                using (var appKey = serviceKey.CreateSubKeyChecked(defaultProgram.ID))
                {
                    // Add flag to remember whether created for capability or access point
                    appKey.SetValue(accessPoint ? FileType.PurposeFlagAccessPoint : FileType.PurposeFlagCapability, "");

                    appKey.SetValue("", target.Feed.Name);

                    FileType.RegisterVerbCapability(appKey, target, defaultProgram, true, handler);

                    // Set callbacks for Windows SPAD
                    using (var installInfoKey = appKey.CreateSubKeyChecked(RegSubKeyInstallInfo))
                    {
                        string exePath = Path.Combine(Locations.InstallBase, "0install-win.exe");
                        installInfoKey.SetValue(RegValueReinstallCommand, new[] {exePath, "integrate", "--machine", "--batch", "--add", "defaults", target.Uri.ToStringRfc()}.JoinEscapeArguments());
                        installInfoKey.SetValue(RegValueShowIconsCommand, new[] {exePath, "integrate", "--machine", "--batch", "--add", MenuEntry.CategoryName, "--add", DesktopIcon.CategoryName, target.Uri.ToStringRfc()}.JoinEscapeArguments());
                        installInfoKey.SetValue(RegValueHideIconsCommand, new[] {exePath, "integrate", "--machine", "--batch", "--remove", MenuEntry.CategoryName, "--remove", DesktopIcon.CategoryName, target.Uri.ToStringRfc()}.JoinEscapeArguments());
                        installInfoKey.SetValue(RegValueIconsVisible, 0, RegistryValueKind.DWord);
                    }

                    if (defaultProgram.Service == Store.Model.Capabilities.DefaultProgram.ServiceMail)
                    {
                        var mailToProtocol = new Store.Model.Capabilities.UrlProtocol {Verbs = {new Verb {Name = Verb.NameOpen}}};
                        using (var mailToKey = appKey.CreateSubKeyChecked(@"Protocols\mailto"))
                            FileType.RegisterVerbCapability(mailToKey, target, mailToProtocol, true, handler);
                    }
                }

                if (accessPoint) serviceKey.SetValue("", defaultProgram.ID);
            }
        }
示例#6
0
        /// <summary>
        /// Unregisters a URL protocol in the current system.
        /// </summary>
        /// <param name="urlProtocol">The URL protocol to remove.</param>
        /// <param name="machineWide">Unregister the URL protocol machine-wide instead of just for the current user.</param>
        /// <param name="accessPoint">Indicates that the handler was the default handler for the protocol.</param>
        /// <exception cref="IOException">A problem occurs while writing to the filesystem or registry.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
        /// <exception cref="InvalidDataException">The data in <paramref name="urlProtocol"/> is invalid.</exception>
        public static void Unregister([NotNull] Store.Model.Capabilities.UrlProtocol urlProtocol, bool machineWide, bool accessPoint = false)
        {
            #region Sanity checks
            if (urlProtocol == null)
            {
                throw new ArgumentNullException(nameof(urlProtocol));
            }
            #endregion

            if (string.IsNullOrEmpty(urlProtocol.ID))
            {
                throw new InvalidDataException("Missing ID");
            }

            var hive = machineWide ? Registry.LocalMachine : Registry.CurrentUser;

            if (urlProtocol.KnownPrefixes.Count == 0)
            {
                if (accessPoint)
                { // Was registered invasively by registering protocol ProgID
                    try
                    {
                        hive.DeleteSubKeyTree(FileType.RegKeyClasses + @"\" + urlProtocol.ID);
                    }
                    #region Error handling
                    catch (ArgumentException)
                    {
                        // Ignore missing registry keys
                    }
                    #endregion
                }
            }
            else
            { // Was registered non-invasively by registering custom ProgID
                if (accessPoint)
                {
                    foreach (var prefix in urlProtocol.KnownPrefixes)
                    {
                        // TODO: Restore previous default
                    }
                }

                // Remove appropriate purpose flag and check if there are others
                bool otherFlags;
                using (var progIDKey = hive.OpenSubKey(FileType.RegKeyClasses + @"\" + FileType.RegKeyPrefix + urlProtocol.ID, writable: true))
                {
                    if (progIDKey == null)
                    {
                        otherFlags = false;
                    }
                    else
                    {
                        progIDKey.DeleteValue(accessPoint ? FileType.PurposeFlagAccessPoint : FileType.PurposeFlagCapability, throwOnMissingValue: false);
                        otherFlags = progIDKey.GetValueNames().Any(name => name.StartsWith(FileType.PurposeFlagPrefix));
                    }
                }

                // Delete ProgID if there are no other references
                if (!otherFlags)
                {
                    try
                    {
                        hive.DeleteSubKeyTree(FileType.RegKeyClasses + @"\" + FileType.RegKeyPrefix + urlProtocol.ID);
                    }
                    #region Error handling
                    catch (ArgumentException)
                    {
                        // Ignore missing registry keys
                    }
                    #endregion
                }
            }
            #endregion
        }