Exemplo n.º 1
0
        /// <summary>
        /// Creates a new Windows shortcut.
        /// </summary>
        /// <param name="path">The location to place the shortcut at.</param>
        /// <param name="target">The target the shortcut shall point to.</param>
        /// <param name="command">The command within <paramref name="target"/> the shortcut shall point to; can be <c>null</c>.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        private static void Create(string path, FeedTarget target, string?command, IIconStore iconStore)
        {
            if (string.IsNullOrEmpty(command))
            {
                command = Command.NameRun;
            }

            var  entryPoint    = target.Feed.GetEntryPoint(command);
            bool needsTerminal = (entryPoint != null && entryPoint.NeedsTerminal);

            string targetPath = Path.Combine(Locations.InstallBase, needsTerminal ? "0install.exe" : "0install-win.exe");

            string arguments = "run ";

            if (!needsTerminal)
            {
                arguments += "--no-wait ";
            }
            if (command != Command.NameRun)
            {
                arguments += "--command " + command.EscapeArgument() + " ";
            }
            arguments += target.Uri.ToStringRfc().EscapeArgument();

            var icon = target.Feed.GetIcon(Icon.MimeTypeIco, command);

            Create(path, targetPath, arguments,
                   iconLocation: (icon == null) ? null : iconStore.GetPath(icon),
                   description: target.Feed.GetBestSummary(CultureInfo.CurrentUICulture, command));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Registers a <see cref="VerbCapability"/> in a registry key.
        /// </summary>
        /// <param name="registryKey">The registry key to write the new data to.</param>
        /// <param name="target">The application being integrated.</param>
        /// <param name="capability">The capability to register.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        /// <param name="machineWide">Assume <paramref name="registryKey"/> is effective machine-wide instead of just for the current user.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occurred 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="capability"/> is invalid.</exception>
        public static void Register(RegistryKey registryKey, FeedTarget target, VerbCapability capability, IIconStore iconStore, bool machineWide)
        {
            #region Sanity checks
            if (capability == null)
            {
                throw new ArgumentNullException(nameof(capability));
            }
            if (iconStore == null)
            {
                throw new ArgumentNullException(nameof(iconStore));
            }
            #endregion

            var icon = capability.GetIcon(Icon.MimeTypeIco) ?? target.Feed.GetIcon(Icon.MimeTypeIco);
            if (icon != null)
            {
                using var iconKey = registryKey.CreateSubKeyChecked("DefaultIcon");
                iconKey.SetValue("", iconStore.GetPath(icon) + ",0");
            }

            foreach (var verb in capability.Verbs)
            {
                if (string.IsNullOrEmpty(verb.Name))
                {
                    throw new InvalidDataException("Missing verb name");
                }
                using var verbKey = registryKey.CreateSubKeyChecked($@"shell\{verb.Name}");
                Register(verbKey, target, verb, iconStore, machineWide);
            }

            // Prevent conflicts with existing entries
            registryKey.DeleteSubKeyTree(@"shell\ddeexec", throwOnMissingSubKey: false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Registers a <see cref="Verb"/> in a registry key.
        /// </summary>
        /// <param name="verbKey">The registry key to write the new data to.</param>
        /// <param name="target">The application being integrated.</param>
        /// <param name="verb">The verb to register.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        /// <param name="machineWide">Assume <paramref name="verbKey"/> is effective machine-wide instead of just for the current user.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occurred 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="verb"/> is invalid.</exception>
        public static void Register(RegistryKey verbKey, FeedTarget target, Verb verb, IIconStore iconStore, bool machineWide)
        {
            string?description = verb.Descriptions.GetBestLanguage(CultureInfo.CurrentUICulture);

            if (!string.IsNullOrEmpty(description))
            {
                verbKey.SetValue("", description);
                verbKey.SetValue("MUIVerb", description);
            }

            if (verb.Extended)
            {
                verbKey.SetValue("Extended", "");
            }

            var icon = target.Feed.GetIcon(Icon.MimeTypeIco, verb.Command);

            if (icon != null)
            {
                verbKey.SetValue("Icon", iconStore.GetPath(icon));
            }

            using var commandKey = verbKey.CreateSubKeyChecked("command");
            commandKey.SetValue("", GetLaunchCommandLine(target, verb, iconStore, machineWide));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Adds an AutoPlay handler registration to the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="autoPlay">The AutoPlay handler information to be applied.</param>
        /// <param name="machineWide">Register the handler machine-wide instead of just for the current user.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        /// <param name="accessPoint">Indicates that the handler should become the default handler for all <see cref="Model.Capabilities.AutoPlay.Events"/>.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occurred 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="autoPlay"/> is invalid.</exception>
        public static void Register(FeedTarget target, Model.Capabilities.AutoPlay autoPlay, IIconStore iconStore, bool machineWide, bool accessPoint = false)
        {
            #region Sanity checks
            if (autoPlay == null)
            {
                throw new ArgumentNullException(nameof(autoPlay));
            }
            if (iconStore == null)
            {
                throw new ArgumentNullException(nameof(iconStore));
            }
            #endregion

            if (string.IsNullOrEmpty(autoPlay.ID))
            {
                throw new InvalidDataException("Missing ID");
            }
            if (string.IsNullOrEmpty(autoPlay.Provider))
            {
                throw new InvalidDataException("Missing provider");
            }

            var verb = autoPlay.Verb;
            if (verb == null)
            {
                throw new InvalidDataException("Missing verb");
            }
            if (string.IsNullOrEmpty(verb.Name))
            {
                throw new InvalidDataException("Missing verb name");
            }

            string handlerName = RegistryClasses.Prefix + autoPlay.ID;
            string progId      = RegistryClasses.Prefix + "AutoPlay." + autoPlay.ID;

            using (var classesKey = RegistryClasses.OpenHive(machineWide))
                using (var verbKey = classesKey.CreateSubKeyChecked($@"{progId}\shell\{verb.Name}"))
                    RegistryClasses.Register(verbKey, target, verb, iconStore, machineWide);

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

            using (var handlerKey = hive.CreateSubKeyChecked($@"{RegKeyHandlers}\{handlerName}"))
            {
                handlerKey.SetValue(accessPoint ? RegistryClasses.PurposeFlagAccessPoint : RegistryClasses.PurposeFlagCapability, "");
                handlerKey.SetValue(RegValueProgID, progId);
                handlerKey.SetValue(RegValueVerb, verb.Name);
                handlerKey.SetValue(RegValueProvider, autoPlay.Provider);
                handlerKey.SetValue(RegValueDescription, autoPlay.Descriptions.GetBestLanguage(CultureInfo.CurrentUICulture) ?? verb.Name);

                var icon = autoPlay.GetIcon(Icon.MimeTypeIco) ?? target.Feed.GetIcon(Icon.MimeTypeIco, verb.Command);
                if (icon != null)
                {
                    handlerKey.SetValue(RegValueIcon, iconStore.GetPath(icon) + ",0");
                }
            }

            foreach (var autoPlayEvent in autoPlay.Events.Except(x => string.IsNullOrEmpty(x.Name)))
            {
                using (var eventKey = hive.CreateSubKeyChecked($@"{RegKeyAssocs}\{autoPlayEvent.Name}"))
                    eventKey.SetValue(handlerName, "");

                if (accessPoint)
                {
                    using var chosenEventKey = hive.CreateSubKeyChecked($@"{RegKeyChosenAssocs}\{autoPlayEvent.Name}");
                    chosenEventKey.SetValue("", handlerName);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Applies application registration to the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="appRegistration">The registration information to be applied.</param>
        /// <param name="verbCapabilities">The capabilities that the application is to be registered with.</param>
        /// <param name="machineWide">Apply the registration machine-wide instead of just for the current user.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
        /// <exception cref="WebException">A problem occurred 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="appRegistration"/> or <paramref name="verbCapabilities"/> is invalid.</exception>
        public static void Register(FeedTarget target, Model.Capabilities.AppRegistration appRegistration, IEnumerable <VerbCapability> verbCapabilities, IIconStore iconStore, bool machineWide)
        {
            #region Sanity checks
            if (appRegistration == null)
            {
                throw new ArgumentNullException(nameof(appRegistration));
            }
            if (verbCapabilities == null)
            {
                throw new ArgumentNullException(nameof(verbCapabilities));
            }
            if (iconStore == null)
            {
                throw new ArgumentNullException(nameof(iconStore));
            }
            #endregion

            if (string.IsNullOrEmpty(appRegistration.ID))
            {
                throw new InvalidDataException("Missing ID");
            }
            if (string.IsNullOrEmpty(appRegistration.CapabilityRegPath))
            {
                throw new InvalidDataException("Invalid CapabilityRegPath");
            }

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

            // TODO: Handle appRegistration.X64
            using (var capabilitiesKey = hive.CreateSubKeyChecked(/*CapabilityPrefix +*/ appRegistration.CapabilityRegPath))
            {
                capabilitiesKey.SetValue(RegValueAppName, target.Feed.Name ?? "");
                capabilitiesKey.SetValue(RegValueAppDescription, target.Feed.Descriptions.GetBestLanguage(CultureInfo.CurrentUICulture) ?? "");

                // Set icon if available
                var icon = target.Feed.GetIcon(Icon.MimeTypeIco);
                if (icon != null)
                {
                    capabilitiesKey.SetValue(RegValueAppIcon, iconStore.GetPath(icon) + ",0");
                }

                verbCapabilities = verbCapabilities.ToArray();

                using (var fileAssocsKey = capabilitiesKey.CreateSubKeyChecked(RegSubKeyFileAssocs))
                {
                    foreach (var fileType in verbCapabilities.OfType <Model.Capabilities.FileType>().Except(x => string.IsNullOrEmpty(x.ID)))
                    {
                        foreach (var extension in fileType.Extensions.Except(x => string.IsNullOrEmpty(x.Value)))
                        {
                            fileAssocsKey.SetValue(extension.Value, RegistryClasses.Prefix + fileType.ID);
                        }
                    }
                }

                using (var urlAssocsKey = capabilitiesKey.CreateSubKeyChecked(RegSubKeyUrlAssocs))
                {
                    foreach (var urlProtocol in verbCapabilities.OfType <Model.Capabilities.UrlProtocol>())
                    {
                        foreach (var prefix in urlProtocol.KnownPrefixes)
                        {
                            urlAssocsKey.SetValue(prefix.Value, RegistryClasses.Prefix + urlProtocol.ID);
                        }
                    }
                }

                using var startMenuKey = capabilitiesKey.CreateSubKeyChecked(RegSubKeyStartMenu);
                foreach (var defaultProgram in verbCapabilities.OfType <Model.Capabilities.DefaultProgram>().Except(x => string.IsNullOrEmpty(x.ID) || string.IsNullOrEmpty(x.Service)))
                {
                    startMenuKey.SetValue(defaultProgram.Service, defaultProgram.ID);
                }
            }

            using var regAppsKey = hive.CreateSubKeyChecked(RegKeyMachineRegisteredApplications);
            regAppsKey.SetValue(appRegistration.ID, /*CapabilityPrefix +*/ appRegistration.CapabilityRegPath);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Builds a stub EXE that executes the "0install run" command.
        /// </summary>
        /// <param name="target">The application to be launched via the stub.</param>
        /// <param name="path">The target path to store the generated EXE file.</param>
        /// <param name="iconStore">Stores icon files downloaded from the web as local files.</param>
        /// <param name="needsTerminal"><c>true</c> to build a CLI stub, <c>false</c> to build a GUI stub.</param>
        /// <param name="command">The command argument to be passed to the the "0install run" command; can be <c>null</c>.</param>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="InvalidOperationException">There was a compilation error while generating the stub EXE.</exception>
        /// <exception cref="IOException">A problem occurred while writing to the filesystem.</exception>
        /// <exception cref="WebException">A problem occurred while downloading additional data (such as icons).</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the filesystem is not permitted.</exception>
        internal static void BuildRunStub(FeedTarget target, string path, IIconStore iconStore, bool needsTerminal, string?command = null)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (iconStore == null)
            {
                throw new ArgumentNullException(nameof(iconStore));
            }
            #endregion

            var compilerParameters = new CompilerParameters
            {
                OutputAssembly        = path,
                GenerateExecutable    = true,
                TreatWarningsAsErrors = true,
                ReferencedAssemblies  = { "System.dll" },
                CompilerOptions       = needsTerminal ? "/target:exe" : "/target:winexe"
            };

            var icon = target.Feed.GetIcon(Icon.MimeTypeIco, command);
            if (icon != null)
            {
                try
                {
                    string iconPath = iconStore.GetPath(icon);
                    new System.Drawing.Icon(iconPath).Dispose(); // Try to parse icon to ensure it is valid
                    compilerParameters.CompilerOptions += " /win32icon:" + iconPath.EscapeArgument();
                }
                #region Error handling
                catch (UriFormatException ex)
                {
                    Log.Warn(ex);
                }
                catch (WebException ex)
                {
                    Log.Warn(ex);
                }
                catch (IOException ex)
                {
                    Log.Warn($"Failed to store {icon}");
                    Log.Warn(ex);
                }
                catch (UnauthorizedAccessException ex)
                {
                    Log.Warn($"Failed to store {icon}");
                    Log.Warn(ex);
                }
                catch (ArgumentException ex)
                {
                    Log.Warn($"Failed to parse {icon}");
                    Log.Warn(ex);
                }
                #endregion
            }

            compilerParameters.CompileCSharp(
                code: GetRunStubCode(target, needsTerminal, command),
                manifest: typeof(StubBuilder).GetEmbeddedString("Stub.manifest"));
        }