Associates a FeedUri with the Feed data aquired from there.
Model.Feed.Uri is only mandatory for remote feeds. This structure associates a FeedUri with all kinds of feeds, local and remote.
コード例 #1
0
        /// <summary>
        /// Creates a new Windows shortcut on the desktop.
        /// </summary>
        /// <param name="desktopIcon">Information about the shortcut to be created.</param>
        /// <param name="target">The target the shortcut shall point to.</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="machineWide">Create the shortcut machine-wide instead of just for the current user.</param>
        public static void Create([NotNull] DesktopIcon desktopIcon, FeedTarget target, [NotNull] ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (desktopIcon == null) throw new ArgumentNullException(nameof(desktopIcon));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            string filePath = GetDesktopPath(desktopIcon.Name, machineWide);
            Create(filePath, target, desktopIcon.Command, handler, machineWide);
        }
コード例 #2
0
        /// <summary>
        /// Creates a new Windows shortcut in the quick launch bar.
        /// </summary>
        /// <param name="quickLaunch">Information about the shortcut to be created.</param>
        /// <param name="target">The target the shortcut shall point to.</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>
        public static void Create(QuickLaunch quickLaunch, FeedTarget target, ITaskHandler handler)
        {
            #region Sanity checks
            if (quickLaunch == null) throw new ArgumentNullException("quickLaunch");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            string filePath = GetQuickLaunchPath(quickLaunch.Name);
            Create(filePath, target, quickLaunch.Command, handler, machineWide: false);
        }
コード例 #3
0
        /// <summary>
        /// Creates a new Windows shortcut in the "Startup" menu.
        /// </summary>
        /// <param name="autoStart">Information about the shortcut to be created.</param>
        /// <param name="target">The target the shortcut shall point to.</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="machineWide">Create the shortcut machine-wide instead of just for the current user.</param>
        public static void Create(AutoStart autoStart, FeedTarget target, ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (autoStart == null) throw new ArgumentNullException("autoStart");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            string filePath = GetStartupPath(autoStart.Name, machineWide);
            Create(filePath, target.GetRunStub(autoStart.Command, handler));
        }
コード例 #4
0
        /// <summary>
        /// Creates a new Windows shortcut in the "Send to" menu.
        /// </summary>
        /// <param name="sendTo">Information about the shortcut to be created.</param>
        /// <param name="target">The target the shortcut shall point to.</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>
        public static void Create(SendTo sendTo, FeedTarget target, ITaskHandler handler)
        {
            #region Sanity checks
            if (sendTo == null) throw new ArgumentNullException(nameof(sendTo));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            string filePath = GetSendToPath(sendTo.Name);
            Create(filePath, target, sendTo.Command, handler, machineWide: false);
        }
コード例 #5
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
        }
コード例 #6
0
ファイル: ComServer.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Registers a COM server in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="comServer">The COM server to be registered.</param>
        /// <param name="machineWide">Register the COM server 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>
        /// <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="comServer"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.ComServer comServer, bool machineWide, [NotNull] ITaskHandler handler)
        {
            #region Sanity checks
            if (comServer == null) throw new ArgumentNullException(nameof(comServer));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

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

            // TODO: Implement
        }
コード例 #7
0
        public void TestAddApp()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test", CapabilityLists = {capabilityList}});
            _integrationManager.AddApp(target);

            _integrationManager.AppList.Entries
                .Should().Equal(new AppEntry {InterfaceUri = FeedTest.Test1Uri, Name = target.Feed.Name, CapabilityLists = {capabilityList}});

            _integrationManager.Invoking(x => x.AddApp(target))
                .ShouldThrow<InvalidOperationException>(because: "Do not allow adding applications to AppList more than once.");
        }
コード例 #8
0
        /// <summary>
        /// Adds a context menu entry to the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="contextMenu">The context menu entry to add.</param>
        /// <param name="machineWide">Add the context menu entry 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>
        /// <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="contextMenu"/> is invalid.</exception>
        public static void Apply(FeedTarget target, Store.Model.Capabilities.ContextMenu contextMenu, bool machineWide, ITaskHandler handler)
        {
            #region Sanity checks
            if (contextMenu == null) throw new ArgumentNullException("contextMenu");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            if (contextMenu.Verb == null) throw new InvalidDataException("Missing verb");
            if (string.IsNullOrEmpty(contextMenu.Verb.Name)) throw new InvalidDataException("Missing verb name");

            // TODO: Implement
        }
コード例 #9
0
        /// <summary>
        /// Registers an application as a candidate for a default program for some service in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="defaultProgram">The default program information to be registered.</param>
        /// <param name="machineWide">Apply the registration 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 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.</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="defaultProgram"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.DefaultProgram defaultProgram, bool machineWide, [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");

            // TODO: Implement
        }
コード例 #10
0
        /// <summary>
        /// Creates a new Windows shortcut in the start menu or on the start page.
        /// </summary>
        /// <param name="menuEntry">Information about the shortcut to be created.</param>
        /// <param name="target">The target the shortcut shall point to.</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="machineWide">Create the shortcut machine-wide instead of just for the current user.</param>
        public static void Create([NotNull] MenuEntry menuEntry, FeedTarget target, [NotNull] ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (menuEntry == null) throw new ArgumentNullException(nameof(menuEntry));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            string dirPath = GetStartMenuCategoryPath(menuEntry.Category, machineWide);
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);

            string filePath = GetStartMenuPath(menuEntry.Category, menuEntry.Name, machineWide);
            Create(filePath, target, menuEntry.Command, handler, machineWide);
        }
コード例 #11
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="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</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="appRegistration"/> or <paramref name="verbCapabilities"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.AppRegistration appRegistration, IEnumerable<VerbCapability> verbCapabilities, bool machineWide, [NotNull] ITaskHandler handler)
        {
            #region Sanity checks
            if (appRegistration == null) throw new ArgumentNullException(nameof(appRegistration));
            if (verbCapabilities == null) throw new ArgumentNullException(nameof(verbCapabilities));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #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, IconProvider.GetIconPath(icon, handler, machineWide) + ",0");

                using (var fileAssocsKey = capabilitiesKey.CreateSubKeyChecked(RegSubKeyFileAssocs))
                {
                    foreach (var fileType in verbCapabilities.OfType<Store.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, FileType.RegKeyPrefix + fileType.ID);
                    }
                }

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

                using (var startMenuKey = capabilitiesKey.CreateSubKeyChecked(RegSubKeyStartMenu))
                {
                    foreach (var defaultProgram in verbCapabilities.OfType<Store.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);
        }
コード例 #12
0
ファイル: AppAlias.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Creates an application alias in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="command">The command within <paramref name="target"/> the alias shall point to; can be <c>null</c>.</param>
        /// <param name="aliasName">The name of the alias to be created.</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="machineWide">Create the alias machine-wide instead of just for the current user.</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>
        public static void Create(FeedTarget target, [CanBeNull] string command, [NotNull] string aliasName, [NotNull] ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(aliasName)) throw new ArgumentNullException(nameof(aliasName));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            if (string.IsNullOrEmpty(aliasName) || aliasName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
                throw new IOException(string.Format(Resources.NameInvalidChars, aliasName));

            // TODO: Find directory in search PATH

            // TODO: Write file
        }
コード例 #13
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("urlProtocol");
            if (handler == null) throw new ArgumentNullException("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);
                        }
                    }
                }
            }
        }
コード例 #14
0
ファイル: AppAlias.cs プロジェクト: modulexcite/0install-win
        /// <summary>
        /// Creates an application alias in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="command">The command within <paramref name="target"/> the alias shall point to; can be <see langword="null"/>.</param>
        /// <param name="aliasName">The name of the alias to be created.</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="machineWide">Create the alias machine-wide instead of just for the current user.</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>
        public static void Create(FeedTarget target, [CanBeNull] string command, [NotNull] string aliasName, [NotNull] ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(aliasName)) throw new ArgumentNullException("aliasName");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            if (string.IsNullOrEmpty(aliasName) || aliasName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
                throw new IOException(string.Format(Resources.NameInvalidChars, aliasName));

            // TODO: Find directory in search PATH
            //string stubDirPath = Locations.GetIntegrationDirPath("0install.net", machineWide, "desktop-integration", "aliases");
            //string stubFilePath = Path.Combine(stubDirPath, aliasName);

            // TODO: Write file
        }
コード例 #15
0
ファイル: AppAlias.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Creates an application alias in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="command">The command within <paramref name="target"/> the alias shall point to; can be <c>null</c>.</param>
        /// <param name="aliasName">The name of the alias to be created.</param>
        /// <param name="machineWide">Create the alias 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>
        /// <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>
        public static void Create(FeedTarget target, [CanBeNull] string command, [NotNull] string aliasName, bool machineWide, [NotNull] ITaskHandler handler)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(aliasName)) throw new ArgumentNullException(nameof(aliasName));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            if (string.IsNullOrEmpty(aliasName) || aliasName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
                throw new IOException(string.Format(Resources.NameInvalidChars, aliasName));

            string stubDirPath = GetStubDir(machineWide);
            PathEnv.AddDir(stubDirPath, machineWide);

            string stubFilePath = Path.Combine(stubDirPath, aliasName + ".exe");
            StubBuilder.BuildRunStub(target, stubFilePath, handler, needsTerminal: true, command: command);
            AddToAppPaths(aliasName + ".exe", stubFilePath, machineWide);
        }
コード例 #16
0
ファイル: AppAlias.cs プロジェクト: modulexcite/0install-win
        /// <summary>
        /// Creates an application alias in the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="command">The command within <paramref name="target"/> the alias shall point to; can be <see langword="null"/>.</param>
        /// <param name="aliasName">The name of the alias to be created.</param>
        /// <param name="machineWide">Create the alias 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>
        /// <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>
        public static void Create(FeedTarget target, [CanBeNull] string command, [NotNull] string aliasName, bool machineWide, [NotNull] ITaskHandler handler)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(aliasName)) throw new ArgumentNullException("aliasName");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            if (string.IsNullOrEmpty(aliasName) || aliasName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
                throw new IOException(string.Format(Resources.NameInvalidChars, aliasName));

            string stubDirPath = Locations.GetIntegrationDirPath("0install.net", machineWide, "desktop-integration", "aliases");
            string stubFilePath = Path.Combine(stubDirPath, aliasName + ".exe");

            target.BuildRunStub(stubFilePath, handler, needsTerminal: true, command: command);
            AddToPath(stubDirPath, machineWide);
            AddToAppPaths(aliasName + ".exe", stubFilePath, machineWide);
        }
コード例 #17
0
ファイル: StubBuilder.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Builds a stub EXE in a well-known location. Future calls with the same arguments will return the same EXE.
        /// </summary>
        /// <param name="target">The application to be launched via the stub.</param>
        /// <param name="command">The command argument to be passed to the the "0install run" command; can be <c>null</c>.</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="machineWide">Store the stub in a machine-wide directory instead of just for the current user.</param>
        /// <returns>The path to the generated stub EXE.</returns>
        /// <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 occurs while writing to the filesystem.</exception>
        /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
        /// <exception cref="InvalidOperationException">Write access to the filesystem is not permitted.</exception>
        public static string GetRunStub(FeedTarget target, [CanBeNull] string command, [NotNull] ITaskHandler handler, bool machineWide = false)
        {
            #region Sanity checks
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            var entryPoint = target.Feed.GetEntryPoint(command);
            string exeName = (entryPoint != null)
                ? entryPoint.BinaryName ?? entryPoint.Command
                : FeedUri.Escape(target.Feed.Name);
            bool needsTerminal = (entryPoint != null && entryPoint.NeedsTerminal);

            string hash = (target.Uri + "#" + command).Hash(SHA256.Create());
            string path = Path.Combine(Locations.GetIntegrationDirPath("0install.net", machineWide, "desktop-integration", "stubs", hash), exeName + ".exe");

            CreateOrUpdateRunStub(target, path, command, needsTerminal, handler);
            return path;
        }
コード例 #18
0
        public void TestRemoveApp()
        {
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test"});
            var appEntry = _integrationManager.AddApp(target);

            // Inject access point into AppEntry (without running integration)
            using (var unapplyFlag = new TemporaryFlagFile("0install-unit-tests"))
            {
                appEntry.AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {UnapplyFlagPath = unapplyFlag}}};

                _integrationManager.RemoveApp(appEntry);
                _integrationManager.AppList.Entries.Should().BeEmpty();

                unapplyFlag.Set.Should().BeTrue(because: "Access points should be unapplied when their AppEntry is removed");
                _integrationManager.Invoking(x => x.RemoveApp(appEntry))
                    .ShouldNotThrow(because: "Allow multiple removals of applications.");
            }
        }
コード例 #19
0
ファイル: RunHook.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Hooks into the creation of new processes on the current thread to inject API hooks.
        /// </summary>
        /// <param name="selections">The implementations chosen for launch.</param>
        /// <param name="executor">The executor used to launch the new process.</param>
        /// <param name="feedManager">Provides access to remote and local <see cref="Feed"/>s. Handles downloading, signature verification and caching.</param>
        /// <param name="handler">A callback object used when the the user needs to be asked questions or informed about download and IO tasks.</param>
        /// <exception cref="ImplementationNotFoundException">The main implementation is not cached (possibly because it is installed natively).</exception>
        public RunHook(Selections selections, IExecutor executor, IFeedManager feedManager, ITaskHandler handler)
        {
            var feed = feedManager[selections.InterfaceUri];
            _target = new FeedTarget(selections.InterfaceUri, feed);

            var mainImplementation = selections.MainImplementation;
            _implementationDir = executor.GetImplementationPath(mainImplementation);
            _mainImplementation = feed[mainImplementation.ID];

            _handler = handler;
            _registryFilter = GetRegistryFilter();
            _relaunchControl = GetRelaunchControl();

            Log.Info("Activating API hooking");
            _hookW = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateProcessW"), new UnsafeNativeMethods.DCreateProcessW(CreateProcessWCallback), null);
            _hookW.ThreadACL.SetInclusiveACL(new[] {Thread.CurrentThread.ManagedThreadId});
            _hookA = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateProcessA"), new UnsafeNativeMethods.DCreateProcessA(CreateProcessACallback), null);
            _hookA.ThreadACL.SetInclusiveACL(new[] {Thread.CurrentThread.ManagedThreadId});
        }
コード例 #20
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);
            }
        }
コード例 #21
0
ファイル: Shortcut.cs プロジェクト: 0install/0install-win
        /// <summary>
        /// Creates a new Windows shortcut.
        /// </summary>
        /// <param name="path">The location to place the shorcut at.</param>
        /// <param name="target">The target the shortcut shall point to.</param>
        /// <param name="command">The command within <paramref name="target"/> the shorcut shall point to; can be <c>null</c>.</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="machineWide">Create the shortcut machine-wide instead of just for the current user.</param>
        private static void Create([NotNull] string path, FeedTarget target, [CanBeNull] string command, [NotNull] ITaskHandler handler, bool machineWide)
        {
            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 : IconProvider.GetIconPath(icon, handler, machineWide),
                description: target.Feed.GetBestSummary(CultureInfo.CurrentUICulture, command));
        }
コード例 #22
0
        /// <summary>
        /// Adds a context menu entry to the current system.
        /// </summary>
        /// <param name="target">The application being integrated.</param>
        /// <param name="contextMenu">The context menu entry to add.</param>
        /// <param name="machineWide">Add the context menu entry 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>
        /// <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="contextMenu"/> is invalid.</exception>
        public static void Apply(FeedTarget target, Store.Model.Capabilities.ContextMenu contextMenu, bool machineWide, ITaskHandler handler)
        {
            #region Sanity checks
            if (contextMenu == null) throw new ArgumentNullException("contextMenu");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            if (contextMenu.Verb == null) throw new InvalidDataException("Missing verb");
            if (string.IsNullOrEmpty(contextMenu.Verb.Name)) throw new InvalidDataException("Missing verb name");

            var hive = machineWide ? Registry.LocalMachine : Registry.CurrentUser;
            foreach (string keyName in GetKeyName(contextMenu.Target))
            {
                using (var verbKey = hive.CreateSubKeyChecked(FileType.RegKeyClasses + @"\" + keyName + @"\shell\" + RegKeyPrefix + contextMenu.Verb.Name))
                {
                    string description = contextMenu.Verb.Descriptions.GetBestLanguage(CultureInfo.CurrentUICulture);
                    if (description != null) verbKey.SetValue("", description);
                    if (contextMenu.Verb.Extended) verbKey.SetValue(FileType.RegValueExtended, "");

                    using (var commandKey = verbKey.CreateSubKeyChecked("command"))
                        commandKey.SetValue("", FileType.GetLaunchCommandLine(target, contextMenu.Verb, machineWide, handler));
                }
            }
        }
コード例 #23
0
        /// <inheritdoc/>
        protected override AppEntry AddAppInternal(FeedTarget target)
        {
            // Prevent double entries
            if (AppList.ContainsEntry(target.Uri)) throw new InvalidOperationException(string.Format(Resources.AppAlreadyInList, target.Feed.Name));

            // Get basic metadata and copy of capabilities from feed
            var appEntry = new AppEntry {InterfaceUri = target.Uri, Name = target.Feed.Name, Timestamp = DateTime.UtcNow};
            appEntry.CapabilityLists.AddRange(target.Feed.CapabilityLists.CloneElements());

            AppList.Entries.Add(appEntry);
            WriteAppDir(appEntry);
            return appEntry;
        }
コード例 #24
0
        /// <summary>
        /// Creates a dialog box for asking the the user to select an <see cref="Command"/>.
        /// </summary>
        /// <param name="target">The application to be launched.</param>
        public SelectCommandDialog(FeedTarget target)
        {
            _target = target;

            InitializeComponent();
        }
コード例 #25
0
        /// <summary>
        /// Generates the C# to be compiled for the stub EXE.
        /// </summary>
        /// <param name="target">The application to be launched via the stub.</param>
        /// <param name="needsTerminal"><see langword="true"/> to build a CLI stub, <see langword="false"/> to build a GUI stub.</param>
        /// <param name="command">The command argument to be passed to the the "0install run" command; can be <see langword="null"/>.</param>
        /// <returns>Generated C# code.</returns>
        private static string GetRunStubCode(FeedTarget target, bool needsTerminal, [CanBeNull] string command = null)
        {
            // Build command-line
            string args = needsTerminal ? "" : "run --no-wait ";
            if (!string.IsNullOrEmpty(command)) args += "--command " + command.EscapeArgument() + " ";
            args += target.Uri.ToStringRfc().EscapeArgument();

            // Load the template code and insert variables
            var code = typeof(StubBuilder).GetEmbedded("stub.template.cs").ReadToString()
                .Replace("[EXE]", Path.Combine(Locations.InstallBase, needsTerminal ? "0launch.exe" : "0install-win.exe")
                    .Replace(@"\", @"\\"));
            code = code.Replace("[ARGUMENTS]", EscapeForCode(args));
            code = code.Replace("[TITLE]", EscapeForCode(target.Feed.GetBestName(CultureInfo.CurrentUICulture, command)));
            return code;
        }
コード例 #26
0
ファイル: FreeDesktop.cs プロジェクト: 0install/0install-win
 public static void Create(MenuEntry menuEntry, FeedTarget target, bool machineWide, ITaskHandler handler)
 {
     throw new NotImplementedException();
 }
コード例 #27
0
ファイル: FreeDesktop.cs プロジェクト: 0install/0install-win
 public static void Create(DesktopIcon desktopIcon, FeedTarget target, bool machineWide, ITaskHandler handler)
 {
     throw new NotImplementedException();
 }
コード例 #28
0
ファイル: AutoPlay.cs プロジェクト: modulexcite/0install-win
        /// <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="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 should become the default handler for all <see cref="Store.Model.Capabilities.AutoPlay.Events"/>.</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="autoPlay"/> is invalid.</exception>
        public static void Register(FeedTarget target, [NotNull] Store.Model.Capabilities.AutoPlay autoPlay, bool machineWide, [NotNull] ITaskHandler handler, bool accessPoint = false)
        {
            #region Sanity checks
            if (autoPlay == null) throw new ArgumentNullException("autoPlay");
            if (handler == null) throw new ArgumentNullException("handler");
            #endregion

            if (string.IsNullOrEmpty(autoPlay.ID)) throw new InvalidDataException("Missing ID");
            if (autoPlay.Verb == null) throw new InvalidDataException("Missing verb");
            if (string.IsNullOrEmpty(autoPlay.Verb.Name)) throw new InvalidDataException("Missing verb name");
            if (string.IsNullOrEmpty(autoPlay.Provider)) throw new InvalidDataException("Missing provider");

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

            using (var commandKey = hive.CreateSubKeyChecked(FileType.RegKeyClasses + @"\" + FileType.RegKeyPrefix + ".AutoPlay" + autoPlay.ID + @"\shell\" + autoPlay.Verb.Name + @"\command"))
                commandKey.SetValue("", FileType.GetLaunchCommandLine(target, autoPlay.Verb, machineWide, handler));

            using (var handlerKey = hive.CreateSubKeyChecked(RegKeyHandlers + @"\" + FileType.RegKeyPrefix + autoPlay.ID))
            {
                // Add flag to remember whether created for capability or access point
                handlerKey.SetValue(accessPoint ? FileType.PurposeFlagAccessPoint : FileType.PurposeFlagCapability, "");

                handlerKey.SetValue(RegValueProgID, FileType.RegKeyPrefix + ".AutoPlay" + autoPlay.ID);
                handlerKey.SetValue(RegValueVerb, autoPlay.Verb.Name);
                handlerKey.SetValue(RegValueProvider, autoPlay.Provider);
                handlerKey.SetValue(RegValueDescription, autoPlay.Descriptions.GetBestLanguage(CultureInfo.CurrentUICulture) ?? autoPlay.Verb.Name);

                var icon = autoPlay.GetIcon(Icon.MimeTypeIco) ?? target.Feed.GetIcon(Icon.MimeTypeIco, autoPlay.Verb.Command);
                if (icon != null)
                    handlerKey.SetValue(RegValueIcon, IconProvider.GetIconPath(icon, handler, machineWide) + ",0");
            }

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

                if (accessPoint)
                {
                    using (var chosenEventKey = hive.CreateSubKeyChecked(RegKeyChosenAssocs + @"\" + autoPlayEvent.Name))
                        chosenEventKey.SetValue("", FileType.RegKeyPrefix + autoPlay.ID);
                }
            }
        }
コード例 #29
0
        public void TestAddApp()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test", CapabilityLists = {capabilityList}});
            _integrationManager.AddApp(target);

            var expectedAppEntry = new AppEntry {InterfaceUri = FeedTest.Test1Uri, Name = target.Feed.Name, CapabilityLists = {capabilityList}};
            CollectionAssert.AreEqual(new[] {expectedAppEntry}, _integrationManager.AppList.Entries);

            Assert.Throws<InvalidOperationException>(() => _integrationManager.AddApp(target), "Do not allow adding applications to AppList more than once.");
        }
コード例 #30
0
        public void TestRepair()
        {
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test"});
            var appEntry = _integrationManager.AddApp(target);

            using (var applyFlag = new TemporaryFlagFile("0install-unit-tests"))
            {
                // Inject access point into AppEntry (without running integration)
                appEntry.AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = applyFlag}}};
                _integrationManager.Repair(uri => new Feed());

                Assert.IsTrue(applyFlag.Set, "Access points should be reapplied");
            }
        }