/// <summary> /// Collects data about well-known URL protocol handlers. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public void CollectProtocolAssocs([NotNull] CommandMapper commandMapper, [NotNull] CapabilityList capabilities) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion foreach (string protocol in ProtocolAssocs.Select(protocolAssoc => protocolAssoc.Key)) { using (var protocolKey = Registry.ClassesRoot.OpenSubKey(protocol)) { if (protocolKey == null) { throw new IOException(protocol + " not found"); } capabilities.Entries.Add(new UrlProtocol { ID = protocol, Descriptions = { RegistryUtils.GetString(@"HKEY_CLASSES_ROOT\" + protocol, valueName: null, defaultValue: protocol) }, Verbs = { GetVerb(protocolKey, commandMapper, "open") } }); } } }
private static CapabilityList GetCapabilityList(CommandMapper commandMapper, SnapshotDiff diff) { var capabilities = new CapabilityList { OS = OS.Windows }; string appName = null, appDescription = null; diff.CollectFileTypes(commandMapper, capabilities); diff.CollectContextMenus(commandMapper, capabilities); diff.CollectAutoPlays(commandMapper, capabilities); diff.CollectDefaultPrograms(commandMapper, capabilities, ref appName); var appRegistration = diff.GetAppRegistration(commandMapper, capabilities, ref appName, ref appDescription); if (appRegistration != null) { capabilities.Entries.Add(appRegistration); } else { // Only collect URL protocols if there wasn't already an application registration that covered them diff.CollectProtocolAssocs(commandMapper, capabilities); } return(capabilities); }
public void TestGetCommand() { var commandNoArgs = new Command { Name = "no-args", Path = "entry.exe" }; var commandArgs1 = new Command { Name = "args1", Path = "entry.exe", Arguments = { "--arg1", "long argument" } }; var commandArgs2 = new Command { Name = "args2", Path = "entry.exe", Arguments = { "--arg2", "long argument" } }; var provider = new CommandMapper("installation directory", new[] { commandNoArgs, commandArgs1, commandArgs2 }); string additionalArgs; Assert.AreSame(commandNoArgs, provider.GetCommand("installation directory" + Path.DirectorySeparatorChar + "entry.exe", out additionalArgs)); Assert.AreEqual("", additionalArgs); Assert.AreSame(commandNoArgs, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1", out additionalArgs)); Assert.AreEqual("--arg1", additionalArgs); Assert.AreSame(commandArgs1, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1 \"long argument\" bla", out additionalArgs)); Assert.AreEqual("bla", additionalArgs); Assert.AreSame(commandArgs2, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg2 \"long argument\" bla", out additionalArgs)); Assert.AreEqual("bla", additionalArgs); Assert.IsNull(provider.GetCommand("Something" + Path.DirectorySeparatorChar + "else.exe", out additionalArgs)); }
public void TestGetCommand() { var commandNoArgs = new Command {Name = "no-args", Path = "entry.exe"}; var commandArgs1 = new Command {Name = "args1", Path = "entry.exe", Arguments = {"--arg1", "long argument"}}; var commandArgs2 = new Command {Name = "args2", Path = "entry.exe", Arguments = {"--arg2", "long argument"}}; var provider = new CommandMapper("installation directory", new[] {commandNoArgs, commandArgs1, commandArgs2}); string additionalArgs; provider.GetCommand("installation directory" + Path.DirectorySeparatorChar + "entry.exe", out additionalArgs) .Should().BeSameAs(commandNoArgs); additionalArgs.Should().Be(""); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1", out additionalArgs) .Should().BeSameAs(commandNoArgs); additionalArgs.Should().Be("--arg1"); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1 \"long argument\" bla", out additionalArgs) .Should().BeSameAs(commandArgs1); additionalArgs.Should().Be("bla"); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg2 \"long argument\" bla", out additionalArgs) .Should().BeSameAs(commandArgs2); additionalArgs.Should().Be("bla"); provider.GetCommand("Something" + Path.DirectorySeparatorChar + "else.exe", out additionalArgs) .Should().BeNull(); }
public void TestGetCommand() { var commandNoArgs = new Command { Name = "no-args", Path = "entry.exe" }; var commandArgs1 = new Command { Name = "args1", Path = "entry.exe", Arguments = { "--arg1", "long argument" } }; var commandArgs2 = new Command { Name = "args2", Path = "entry.exe", Arguments = { "--arg2", "long argument" } }; var provider = new CommandMapper("installation directory", new[] { commandNoArgs, commandArgs1, commandArgs2 }); string additionalArgs; provider.GetCommand("installation directory" + Path.DirectorySeparatorChar + "entry.exe", out additionalArgs) .Should().BeSameAs(commandNoArgs); additionalArgs.Should().Be(""); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1", out additionalArgs) .Should().BeSameAs(commandNoArgs); additionalArgs.Should().Be("--arg1"); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1 \"long argument\" bla", out additionalArgs) .Should().BeSameAs(commandArgs1); additionalArgs.Should().Be("bla"); provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg2 \"long argument\" bla", out additionalArgs) .Should().BeSameAs(commandArgs2); additionalArgs.Should().Be("bla"); provider.GetCommand("Something" + Path.DirectorySeparatorChar + "else.exe", out additionalArgs) .Should().BeNull(); }
private static Verb GetVerb([NotNull] RegistryKey typeKey, [NotNull] CommandMapper commandMapper, [NotNull] string verbName) { #region Sanity checks if (typeKey == null) { throw new ArgumentNullException("typeKey"); } if (string.IsNullOrEmpty(verbName)) { throw new ArgumentNullException("verbName"); } if (commandMapper == null) { throw new ArgumentNullException("commandMapper"); } #endregion using (var verbKey = typeKey.OpenSubKey(@"shell\" + verbName)) { if (verbKey == null) { return(null); } string description = verbKey.GetValue("", "").ToString(); string commandLine; using (var commandKey = verbKey.OpenSubKey("command")) { if (commandKey == null) { return(null); } commandLine = commandKey.GetValue("", "").ToString(); } string additionalArgs; var command = commandMapper.GetCommand(commandLine, out additionalArgs); if (command == null) { return(null); } string commandName = command.Name; if (commandName == Command.NameRun) { commandName = null; } var verb = new Verb { Name = verbName, Command = commandName, Arguments = additionalArgs }; if (!string.IsNullOrEmpty(description)) { verb.Descriptions.Add(description); } return(verb); } }
/// <summary> /// Collects data about URL protocol handlers indicated by registered application capabilities. /// </summary> /// <param name="capsKey">A registry key containing capability information for a registered application.</param> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> private static void CollectProtocolAssocsEx(RegistryKey capsKey, CommandMapper commandMapper, CapabilityList capabilities) { #region Sanity checks if (capsKey == null) { throw new ArgumentNullException(nameof(capsKey)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } #endregion using var urlAssocKey = capsKey.OpenSubKey(DesktopIntegration.Windows.AppRegistration.RegSubKeyUrlAssocs); if (urlAssocKey == null) { return; } foreach (string protocol in urlAssocKey.GetValueNames()) { string progID = urlAssocKey.GetValue(protocol)?.ToString(); if (string.IsNullOrEmpty(progID)) { continue; } using var progIDKey = Registry.ClassesRoot.OpenSubKey(progID); if (progIDKey == null) { continue; } var prefix = new KnownProtocolPrefix { Value = protocol }; var existing = capabilities.GetCapability <UrlProtocol>(progID); if (existing == null) { var capability = new UrlProtocol { ID = progID, Descriptions = { progIDKey.GetValue("", defaultValue: "").ToString() }, KnownPrefixes = { prefix } }; capability.Verbs.AddRange(GetVerbs(progIDKey, commandMapper)); capabilities.Entries.Add(capability); } else { existing.KnownPrefixes.Add(prefix); } } }
/// <summary> /// Retrieves data about a verb (an executable command) from the registry. /// </summary> /// <param name="typeKey">The registry key containing information about the file type / protocol the verb belongs to.</param> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="verbName">The internal name of the verb.</param> /// <returns>The detected <see cref="Verb"/> or an empty <see cref="Verb"/> if no match was found.</returns> private static Verb?GetVerb(RegistryKey typeKey, CommandMapper commandMapper, string verbName) { #region Sanity checks if (typeKey == null) { throw new ArgumentNullException(nameof(typeKey)); } if (string.IsNullOrEmpty(verbName)) { throw new ArgumentNullException(nameof(verbName)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion using var verbKey = typeKey.OpenSubKey(@"shell\" + verbName); if (verbKey == null) { return(null); } string description = verbKey.GetValue("")?.ToString(); string commandLine; using (var commandKey = verbKey.OpenSubKey("command")) { if (commandKey == null) { return(null); } commandLine = commandKey.GetValue("")?.ToString(); } if (string.IsNullOrEmpty(commandLine)) { return(null); } var command = commandMapper.GetCommand(commandLine, out string additionalArgs); if (command == null) { return(null); } var verb = new Verb { Name = verbName, Command = (command.Name == Command.NameRun) ? null : command.Name, ArgumentsLiteral = additionalArgs }; if (!string.IsNullOrEmpty(description)) { verb.Descriptions.Add(description); } return(verb); }
/// <summary> /// Retrieves data about registered applications. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <param name="appName">Is set to the name of the application as displayed to the user; unchanged if the name was not found.</param> /// <param name="appDescription">Is set to a user-friendly description of the application; unchanged if the name was not found.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public AppRegistration GetAppRegistration([NotNull] CommandMapper commandMapper, [NotNull] CapabilityList capabilities, ref string appName, ref string appDescription) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException("capabilities"); } if (commandMapper == null) { throw new ArgumentNullException("commandMapper"); } #endregion // Ambiguity warnings if (RegisteredApplications.Length == 0) { return(null); } if (RegisteredApplications.Length > 1) { Log.Warn(Resources.MultipleRegisteredAppsDetected); } // Get registry path pointer string appRegName = RegisteredApplications[0]; var capabilitiesRegPath = RegistryUtils.GetString(@"HKEY_LOCAL_MACHINE\" + DesktopIntegration.Windows.AppRegistration.RegKeyMachineRegisteredApplications, appRegName); if (string.IsNullOrEmpty(capabilitiesRegPath)) { return(null); } bool x64; using (var capsKey = RegistryUtils.OpenHklmKey(capabilitiesRegPath, out x64)) { if (string.IsNullOrEmpty(appName)) { appName = capsKey.GetValue(DesktopIntegration.Windows.AppRegistration.RegValueAppName, "").ToString(); } if (string.IsNullOrEmpty(appDescription)) { appDescription = capsKey.GetValue(DesktopIntegration.Windows.AppRegistration.RegValueAppDescription, "").ToString(); } CollectProtocolAssocsEx(capsKey, commandMapper, capabilities); CollectFileAssocsEx(capsKey, capabilities); // Note: Contenders for StartMenu entries are detected elsewhere return(new AppRegistration { ID = appRegName, CapabilityRegPath = capabilitiesRegPath, X64 = x64 }); } }
/// <summary> /// Finishes the capture process after <see cref="Diff"/> has been called an <see cref="FeedBuilder.MainCandidate"/> has been set. /// </summary> /// <exception cref="InvalidOperationException"><see cref="Diff"/> was not called or <see cref="FeedBuilder.MainCandidate"/> is not set.</exception> /// <exception cref="IOException">There was an error accessing the registry or file system.</exception> /// <exception cref="UnauthorizedAccessException">Access to the registry or file system was not permitted.</exception> public void Finish() { if (_diff == null || InstallationDir == null) { throw new InvalidOperationException("Diff() must be called first."); } _feedBuilder.GenerateCommands(); var commandMapper = new CommandMapper(InstallationDir, _feedBuilder.Commands); _feedBuilder.CapabilityList = GetCapabilityList(commandMapper, _diff); }
/// <summary> /// Collects data about default programs. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <param name="appName">Is set to the name of the application as displayed to the user; unchanged if the name was not found.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public void CollectDefaultPrograms([NotNull] CommandMapper commandMapper, [NotNull] CapabilityList capabilities, ref string appName) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion // Ambiguity warnings if (ServiceAssocs.Length > 1) { Log.Warn(Resources.MultipleDefaultProgramsDetected); } foreach (var serviceAssoc in ServiceAssocs) { string service = serviceAssoc.Key; string client = serviceAssoc.Value; using (var clientKey = Registry.LocalMachine.OpenSubKey(DesktopIntegration.Windows.DefaultProgram.RegKeyMachineClients + @"\" + service + @"\" + client)) { if (clientKey == null) { continue; } if (string.IsNullOrEmpty(appName)) { appName = clientKey.GetValue("", "").ToString(); } if (string.IsNullOrEmpty(appName)) { appName = clientKey.GetValue(DesktopIntegration.Windows.DefaultProgram.RegValueLocalizedName, "").ToString(); } var defaultProgram = new DefaultProgram { ID = client, Service = service }; defaultProgram.Verbs.AddRange(GetVerbs(clientKey, commandMapper)); defaultProgram.InstallCommands = GetInstallCommands(clientKey, commandMapper.InstallationDir); capabilities.Entries.Add(defaultProgram); } } }
/// <summary> /// Collects data about URL protocol handlers indicated by registered application capabilities. /// </summary> /// <param name="capsKey">A registry key containing capability information for a registered application.</param> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> private static void CollectProtocolAssocsEx([NotNull] RegistryKey capsKey, [NotNull] CommandMapper commandMapper, [NotNull] CapabilityList capabilities) { #region Sanity checks if (capsKey == null) { throw new ArgumentNullException("capsKey"); } if (commandMapper == null) { throw new ArgumentNullException("commandMapper"); } if (capabilities == null) { throw new ArgumentNullException("capabilities"); } #endregion using (var urlAssocKey = capsKey.OpenSubKey(DesktopIntegration.Windows.AppRegistration.RegSubKeyUrlAssocs)) { if (urlAssocKey == null) { return; } // TODO: Fold multiple prefixes pointing to one protocol together foreach (string protocol in urlAssocKey.GetValueNames()) { string progID = urlAssocKey.GetValue(protocol, "").ToString(); using (var progIDKey = Registry.ClassesRoot.OpenSubKey(progID)) { if (progIDKey == null) { continue; } var capability = new UrlProtocol { ID = progID, Descriptions = { progIDKey.GetValue("", "").ToString() }, KnownPrefixes = { new KnownProtocolPrefix { Value = protocol } } }; capability.Verbs.AddRange(GetVerbs(progIDKey, commandMapper)); capabilities.Entries.Add(capability); } } } }
/// <summary> /// Retrieves data about multiple verbs (executable commands) from the registry. /// </summary> /// <param name="typeKey">The registry key containing information about the file type / protocol the verbs belong to.</param> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <returns>A list of detected <see cref="Verb"/>.</returns> private static IEnumerable <Verb> GetVerbs(RegistryKey typeKey, CommandMapper commandMapper) { #region Sanity checks if (typeKey == null) { throw new ArgumentNullException(nameof(typeKey)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion return(RegUtils.GetSubKeyNames(typeKey, "shell").Select(verbName => GetVerb(typeKey, commandMapper, verbName)).WhereNotNull()); }
/// <summary> /// Collects data about file types and also URL protocol handlers. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public void CollectFileTypes(CommandMapper commandMapper, CapabilityList capabilities) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion capabilities.Entries.AddRange(( from progID in ProgIDs where !string.IsNullOrEmpty(progID) select GetFileType(progID, commandMapper)).WhereNotNull()); }
/// <summary> /// Collects data about AutoPlay handlers. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public void CollectAutoPlays([NotNull] CommandMapper commandMapper, [NotNull] CapabilityList capabilities) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion capabilities.Entries.AddRange(AutoPlayHandlersUser .Select(handler => GetAutoPlay(handler, Registry.CurrentUser, AutoPlayAssocsUser, commandMapper)) .WhereNotNull()); capabilities.Entries.AddRange(AutoPlayHandlersMachine .Select(handler => GetAutoPlay(handler, Registry.LocalMachine, AutoPlayAssocsMachine, commandMapper)) .WhereNotNull()); }
public void TestGetCommand() { var commandNoArgs = new Command {Name = "no-args", Path = "entry.exe"}; var commandArgs1 = new Command {Name = "args1", Path = "entry.exe", Arguments = {"--arg1", "long argument"}}; var commandArgs2 = new Command {Name = "args2", Path = "entry.exe", Arguments = {"--arg2", "long argument"}}; var provider = new CommandMapper("installation directory", new[] {commandNoArgs, commandArgs1, commandArgs2}); string additionalArgs; Assert.AreSame(commandNoArgs, provider.GetCommand("installation directory" + Path.DirectorySeparatorChar + "entry.exe", out additionalArgs)); Assert.AreEqual("", additionalArgs); Assert.AreSame(commandNoArgs, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1", out additionalArgs)); Assert.AreEqual("--arg1", additionalArgs); Assert.AreSame(commandArgs1, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg1 \"long argument\" bla", out additionalArgs)); Assert.AreEqual("bla", additionalArgs); Assert.AreSame(commandArgs2, provider.GetCommand("\"installation directory" + Path.DirectorySeparatorChar + "entry.exe\" --arg2 \"long argument\" bla", out additionalArgs)); Assert.AreEqual("bla", additionalArgs); Assert.IsNull(provider.GetCommand("Something" + Path.DirectorySeparatorChar + "else.exe", out additionalArgs)); }
/// <summary> /// Retrieves data about a specific file type or URL protocol from a snapshot diff. /// </summary> /// <param name="progID">The programmatic identifier of the file type.</param> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <returns>Data about the file type or <see paramref="null"/> if no file type for this <paramref name="progID"/> was detected.</returns> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> private VerbCapability?GetFileType(string progID, CommandMapper commandMapper) { #region Sanity checks if (string.IsNullOrEmpty(progID)) { throw new ArgumentNullException(nameof(progID)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion using var progIDKey = Registry.ClassesRoot.OpenSubKey(progID); if (progIDKey == null) { return(null); } VerbCapability capability; if (progIDKey.GetValue(DesktopIntegration.Windows.UrlProtocol.ProtocolIndicator) == null) { // Normal file type var fileType = new FileType { ID = progID }; foreach (var fileAssoc in FileAssocs.Where(fileAssoc => fileAssoc.Value == progID && !string.IsNullOrEmpty(fileAssoc.Key))) { using var assocKey = Registry.ClassesRoot.OpenSubKey(fileAssoc.Key); if (assocKey == null) { continue; } fileType.Extensions.Add(new FileTypeExtension { Value = fileAssoc.Key, MimeType = assocKey.GetValue(DesktopIntegration.Windows.FileType.RegValueContentType)?.ToString(), PerceivedType = assocKey.GetValue(DesktopIntegration.Windows.FileType.RegValuePerceivedType)?.ToString() }); } capability = fileType; } else { // URL protocol handler capability = new UrlProtocol { ID = progID }; } var description = progIDKey.GetValue(DesktopIntegration.Windows.FileType.RegValueFriendlyName) ?? progIDKey.GetValue(""); if (description != null) { capability.Descriptions.Add(description.ToString()); } capability.Verbs.AddRange(GetVerbs(progIDKey, commandMapper)); // Only return capabilities that have verbs associated with them return(capability.Verbs.Count == 0 ? null : capability); }
/// <summary> /// Finishes the capture process after <see cref="Diff"/> has been called an <see cref="FeedBuilder.MainCandidate"/> has been set. /// </summary> /// <exception cref="InvalidOperationException"><see cref="Diff"/> was not called or <see cref="FeedBuilder.MainCandidate"/> is not set.</exception> /// <exception cref="IOException">There was an error accessing the registry or file system.</exception> /// <exception cref="UnauthorizedAccessException">Access to the registry or file system was not permitted.</exception> public void Finish() { if (_diff == null || InstallationDir == null) throw new InvalidOperationException("Diff() must be called first."); _feedBuilder.GenerateCommands(); var commandMapper = new CommandMapper(InstallationDir, _feedBuilder.Commands); _feedBuilder.CapabilityList = GetCapabilityList(commandMapper, _diff); }
private static CapabilityList GetCapabilityList(CommandMapper commandMapper, SnapshotDiff diff) { var capabilities = new CapabilityList {OS = OS.Windows}; string appName = null, appDescription = null; diff.CollectFileTypes(commandMapper, capabilities); diff.CollectContextMenus(commandMapper, capabilities); diff.CollectAutoPlays(commandMapper, capabilities); diff.CollectDefaultPrograms(commandMapper, capabilities, ref appName); var appRegistration = diff.GetAppRegistration(commandMapper, capabilities, ref appName, ref appDescription); if (appRegistration != null) capabilities.Entries.Add(appRegistration); else { // Only collect URL protocols if there wasn't already an application registration that covered them diff.CollectProtocolAssocs(commandMapper, capabilities); } return capabilities; }
/// <summary> /// Collects data about context menu entries. /// </summary> /// <param name="commandMapper">Provides best-match command-line to <see cref="Command"/> mapping.</param> /// <param name="capabilities">The capability list to add the collected data to.</param> /// <exception cref="IOException">There was an error accessing the registry.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the registry was not permitted.</exception> public void CollectContextMenus(CommandMapper commandMapper, CapabilityList capabilities) { #region Sanity checks if (capabilities == null) { throw new ArgumentNullException(nameof(capabilities)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion using (var progIDKey = Registry.ClassesRoot.OpenSubKey(DesktopIntegration.Windows.ContextMenu.RegKeyClassesFiles)) { if (progIDKey == null) { throw new IOException("Registry key not found"); } foreach (string entry in ContextMenuFiles) { capabilities.Entries.Add(new ContextMenu { ID = "files-" + entry, Target = ContextMenuTarget.Files, Verbs = { GetVerb(progIDKey, commandMapper, entry) } }); } } using (var progIDKey = Registry.ClassesRoot.OpenSubKey(DesktopIntegration.Windows.ContextMenu.RegKeyClassesExecutableFiles[0])) { if (progIDKey == null) { throw new IOException("Registry key not found"); } foreach (string entry in ContextMenuExecutableFiles) { capabilities.Entries.Add(new ContextMenu { ID = "executable-files-" + entry, Target = ContextMenuTarget.ExecutableFiles, Verbs = { GetVerb(progIDKey, commandMapper, entry) } }); } } using (var progIDKey = Registry.ClassesRoot.OpenSubKey(DesktopIntegration.Windows.ContextMenu.RegKeyClassesDirectories)) { if (progIDKey == null) { throw new IOException("Registry key not found"); } foreach (string entry in ContextMenuDirectories) { capabilities.Entries.Add(new ContextMenu { ID = "directories-" + entry, Target = ContextMenuTarget.Directories, Verbs = { GetVerb(progIDKey, commandMapper, entry) } }); } } using (var progIDKey = Registry.ClassesRoot.OpenSubKey(DesktopIntegration.Windows.ContextMenu.RegKeyClassesAll)) { if (progIDKey == null) { throw new IOException("Registry key not found"); } foreach (string entry in ContextMenuAll) { capabilities.Entries.Add(new ContextMenu { ID = "all-" + entry, Target = ContextMenuTarget.Directories, Verbs = { GetVerb(progIDKey, commandMapper, entry) } }); } } }
private static Capability GetAutoPlay([NotNull] string handler, [NotNull] RegistryKey hive, [NotNull, ItemNotNull] IEnumerable <ComparableTuple <string> > autoPlayAssocs, [NotNull] CommandMapper commandMapper) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } if (hive == null) { throw new ArgumentNullException(nameof(hive)); } if (autoPlayAssocs == null) { throw new ArgumentNullException(nameof(autoPlayAssocs)); } if (commandMapper == null) { throw new ArgumentNullException(nameof(commandMapper)); } #endregion using (var handlerKey = hive.OpenSubKey(DesktopIntegration.Windows.AutoPlay.RegKeyHandlers + @"\" + handler)) { if (handlerKey == null) { return(null); } string progID = handlerKey.GetValue(DesktopIntegration.Windows.AutoPlay.RegValueProgID, "").ToString(); string verbName = handlerKey.GetValue(DesktopIntegration.Windows.AutoPlay.RegValueVerb, "").ToString(); using (var progIDKey = Registry.ClassesRoot.OpenSubKey(progID)) { if (progIDKey == null) { throw new IOException(progID + " key not found"); } var autoPlay = new AutoPlay { ID = handler, Provider = handlerKey.GetValue(DesktopIntegration.Windows.AutoPlay.RegValueProvider, "").ToString(), Descriptions = { handlerKey.GetValue(DesktopIntegration.Windows.AutoPlay.RegValueDescription, "").ToString() }, Verb = GetVerb(progIDKey, commandMapper, verbName) }; autoPlay.Events.AddRange( from autoPlayAssoc in autoPlayAssocs where autoPlayAssoc.Value == handler select new AutoPlayEvent { Name = autoPlayAssoc.Key }); return(autoPlay); } } }