public void Win32ProgramRepositoryMustCallOnAppDeletedForLnkAppsWhenDeletedEventIsRaised(string directory, string path)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            FileSystemEventArgs    e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path);

            // ShellLinkHelper must be mocked for lnk applications
            var mockShellLink = new Mock <IShellLinkHelper>();

            mockShellLink.Setup(m => m.RetrieveTargetPath(It.IsAny <string>())).Returns(string.Empty);
            Win32Program.Helper = mockShellLink.Object;

            string       fullPath = directory + "\\" + path;
            Win32Program item     = new Win32Program
            {
                Name            = "path",
                ExecutableName  = "path.exe",
                ParentDirectory = "directory",
                FullPath        = "directory\\path.exe",
                LnkResolvedPath = "directory\\path.lnk", // This must be equal for lnk applications
            };

            win32ProgramRepository.Add(item);

            // Act
            _fileSystemMocks[0].Raise(m => m.Deleted += null, e);

            // Assert
            Assert.AreEqual(0, win32ProgramRepository.Count());
        }
        public void Win32RepositoryMustNotStoreDuplicatesWhileAddingItemsWithSameHashCode(string name, string exename, string fullPath, string description1, string description2)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);

            Win32Program item1 = new Win32Program
            {
                Name           = name,
                ExecutableName = exename,
                FullPath       = fullPath,
                Description    = description1,
            };

            Win32Program item2 = new Win32Program
            {
                Name           = name,
                ExecutableName = exename,
                FullPath       = fullPath,
                Description    = description2,
            };

            // Act
            win32ProgramRepository.Add(item1);

            Assert.AreEqual(1, win32ProgramRepository.Count());

            // To add an item with the same hashCode, ie, same name, exename and fullPath
            win32ProgramRepository.Add(item2);

            // Assert, count still remains 1 because they are duplicate items
            Assert.AreEqual(1, win32ProgramRepository.Count());
        }
        public void Win32ProgramRepositoryMustCallOnAppRenamedForExeAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            RenamedEventArgs       e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath);

            string oldFullPath = directory + "\\" + oldpath;
            string newFullPath = directory + "\\" + newpath;

            // FileVersionInfo must be mocked for exe applications
            var mockFileVersionInfo = new Mock <IFileVersionInfoWrapper>();

            mockFileVersionInfo.Setup(m => m.GetVersionInfo(It.IsAny <string>())).Returns((FileVersionInfo)null);
            Win32Program.FileVersionInfoWrapper = mockFileVersionInfo.Object;

            Win32Program olditem = Win32Program.GetAppFromPath(oldFullPath);
            Win32Program newitem = Win32Program.GetAppFromPath(newFullPath);

            win32ProgramRepository.Add(olditem);

            // Act
            _fileSystemMocks[0].Raise(m => m.Renamed += null, e);

            // Assert
            Assert.AreEqual(1, win32ProgramRepository.Count());
            Assert.IsTrue(win32ProgramRepository.Contains(newitem));
            Assert.IsFalse(win32ProgramRepository.Contains(olditem));
        }
        public void Win32ProgramRepositoryMustCallOnAppRenamedForUrlAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            RenamedEventArgs       e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath);

            // File.ReadAllLines must be mocked for url applications
            var mockFile = new Mock <IFile>();

            mockFile.Setup(m => m.ReadAllLines(It.IsAny <string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
            Win32Program.FileWrapper = mockFile.Object;

            string oldFullPath = directory + "\\" + oldpath;
            string newFullPath = directory + "\\" + newpath;

            Win32Program olditem = Win32Program.GetAppFromPath(oldFullPath);
            Win32Program newitem = Win32Program.GetAppFromPath(newFullPath);

            win32ProgramRepository.Add(olditem);

            // Act
            _fileSystemMocks[0].Raise(m => m.Renamed += null, e);

            // Assert
            Assert.AreEqual(1, win32ProgramRepository.Count());
            Assert.IsTrue(win32ProgramRepository.Contains(newitem));
            Assert.IsFalse(win32ProgramRepository.Contains(olditem));
        }
示例#5
0
        private static Win32Program CreateWin32Program(string path)
        {
            try
            {
                var p = new Win32Program
                {
                    Name             = Path.GetFileNameWithoutExtension(path),
                    ExecutableName   = Path.GetFileName(path),
                    IcoPath          = path,
                    FullPath         = path.ToLower(CultureInfo.CurrentCulture),
                    UniqueIdentifier = path,
                    ParentDirectory  = Directory.GetParent(path).FullName,
                    Description      = string.Empty,
                    Valid            = true,
                    Enabled          = true,
                    AppType          = (uint)ApplicationTypes.WIN32_APPLICATION,
                };
                return(p);
            }
            catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException)
            {
                ProgramLogger.LogException(
                    $"|Win32|Win32Program|{path}" +
                    $"|Permission denied when trying to load the program from {path}", e);

                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }
        }
        public void Win32ProgramRepositoryMustCallOnAppDeletedForApprefAppsWhenDeletedEventIsRaised(string directory, string path)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            FileSystemEventArgs    e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path);

            string       fullPath = directory + "\\" + path;
            Win32Program item     = Win32Program.GetAppFromPath(fullPath);

            win32ProgramRepository.Add(item);

            // Act
            _fileSystemMocks[0].Raise(m => m.Deleted += null, e);

            // Assert
            Assert.AreEqual(0, win32ProgramRepository.Count());
        }
示例#7
0
        // Function to get the Win32 application, given the path to the application
        public static Win32Program GetAppFromPath(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            Win32Program app             = null;
            const string exeExtension    = ".exe";
            const string lnkExtension    = ".lnk";
            const string urlExtenion     = ".url";
            const string apprefExtension = ".appref-ms";

            string extension = Path.GetExtension(path);

            if (extension.Equals(exeExtension, StringComparison.OrdinalIgnoreCase))
            {
                app = ExeProgram(path);
            }
            else if (extension.Equals(lnkExtension, StringComparison.OrdinalIgnoreCase))
            {
                app = LnkProgram(path);
            }
            else if (extension.Equals(apprefExtension, StringComparison.OrdinalIgnoreCase))
            {
                app = CreateWin32Program(path);
            }
            else if (extension.Equals(urlExtenion, StringComparison.OrdinalIgnoreCase))
            {
                app = InternetShortcutProgram(path);
            }

            // if the app is valid, only then return the application, else return null
            if (app?.Valid ?? false)
            {
                return(app);
            }
            else
            {
                return(null);
            }
        }
示例#8
0
        public void Win32ProgramRepositoryMustCallOnAppRenamedForLnkAppsWhenRenamedEventIsRaised(string directory, string oldpath, string path)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch);
            RenamedEventArgs       e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, path, oldpath);

            string oldFullPath = directory + "\\" + oldpath;
            string fullPath    = directory + "\\" + path;
            string linkingTo   = Directory.GetCurrentDirectory();

            // ShellLinkHelper must be mocked for lnk applications
            var mockShellLink = new Mock <IShellLinkHelper>();

            mockShellLink.Setup(m => m.RetrieveTargetPath(It.IsAny <string>())).Returns(linkingTo);
            Win32Program.ShellLinkHelper = mockShellLink.Object;

            // old item and new item are the actual items when they are in existence
            Win32Program olditem = new Win32Program
            {
                Name           = "oldpath",
                ExecutableName = oldpath,
                FullPath       = linkingTo,
            };

            Win32Program newitem = new Win32Program
            {
                Name           = "path",
                ExecutableName = path,
                FullPath       = linkingTo,
            };

            win32ProgramRepository.Add(olditem);

            // Act
            _fileSystemMocks[0].Raise(m => m.Renamed += null, e);

            // Assert
            Assert.AreEqual(1, win32ProgramRepository.Count());
            Assert.IsTrue(win32ProgramRepository.Contains(newitem));
            Assert.IsFalse(win32ProgramRepository.Contains(olditem));
        }
示例#9
0
        private static Win32Program CreateWin32Program(string path)
        {
            try
            {
                var p = new Win32Program
                {
                    Name           = Path.GetFileNameWithoutExtension(path),
                    ExecutableName = Path.GetFileName(path),
                    IcoPath        = path,

                    // Using CurrentCulture since this is user facing
                    FullPath         = path.ToLower(CultureInfo.CurrentCulture),
                    UniqueIdentifier = path,
                    ParentDirectory  = Directory.GetParent(path).FullName,
                    Description      = string.Empty,
                    Valid            = true,
                    Enabled          = true,
                    AppType          = ApplicationType.Win32Application,
                };
                return(p);
            }
            catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException)
            {
                ProgramLogger.Exception($"|Permission denied when trying to load the program from {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);

                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }
            catch (Exception e)
            {
                ProgramLogger.Exception($"|An unexpected error occurred in the calling method CreateWin32Program at {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);

                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }
        }
示例#10
0
        // Function to get the Win32 application, given the path to the application
        public static Win32Program GetAppFromPath(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            Win32Program app = null;

            ApplicationType appType = GetAppTypeFromPath(path);

            if (appType == ApplicationType.Win32Application)
            {
                app = ExeProgram(path);
            }
            else if (appType == ApplicationType.ShortcutApplication)
            {
                app = LnkProgram(path);
            }
            else if (appType == ApplicationType.ApprefApplication)
            {
                app         = CreateWin32Program(path);
                app.AppType = ApplicationType.ApprefApplication;
            }
            else if (appType == ApplicationType.InternetShortcutApplication)
            {
                app = InternetShortcutProgram(path);
            }

            // if the app is valid, only then return the application, else return null
            if (app?.Valid ?? false)
            {
                return(app);
            }
            else
            {
                return(null);
            }
        }
        public void Win32ProgramRepositoryMustCallOnAppRenamedForApprefAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            RenamedEventArgs       e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath);

            string oldFullPath = directory + "\\" + oldpath;
            string newFullPath = directory + "\\" + newpath;

            Win32Program olditem = Win32Program.GetAppFromPath(oldFullPath);
            Win32Program newitem = Win32Program.GetAppFromPath(newFullPath);

            win32ProgramRepository.Add(olditem);

            // Act
            _fileSystemMocks[0].Raise(m => m.Renamed += null, e);

            // Assert
            Assert.AreEqual(1, win32ProgramRepository.Count());
            Assert.IsTrue(win32ProgramRepository.Contains(newitem));
            Assert.IsFalse(win32ProgramRepository.Contains(olditem));
        }
        public void Win32ProgramRepositoryMustCallOnAppDeletedForExeAppsWhenDeletedEventIsRaised(string directory, string path)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage <IList <Win32Program> >("Win32"), _settings, _pathsToWatch);
            FileSystemEventArgs    e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path);

            // FileVersionInfo must be mocked for exe applications
            var mockFileVersionInfo = new Mock <IFileVersionInfoWrapper>();

            mockFileVersionInfo.Setup(m => m.GetVersionInfo(It.IsAny <string>())).Returns((FileVersionInfo)null);
            Win32Program.FileVersionInfoWrapper = mockFileVersionInfo.Object;

            string       fullPath = directory + "\\" + path;
            Win32Program item     = Win32Program.GetAppFromPath(fullPath);

            win32ProgramRepository.Add(item);

            // Act
            _fileSystemMocks[0].Raise(m => m.Deleted += null, e);

            // Assert
            Assert.AreEqual(0, win32ProgramRepository.Count());
        }
        public void Win32ProgramRepositoryMustCallOnAppDeletedForUrlAppsWhenDeletedEventIsRaised(string directory, string path)
        {
            // Arrange
            Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch);
            FileSystemEventArgs    e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path);

            // File.ReadAllLines must be mocked for url applications
            var mockFile = new Mock <IFile>();

            mockFile.Setup(m => m.ReadLines(It.IsAny <string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
            Win32Program.FileWrapper = mockFile.Object;

            string       fullPath = directory + "\\" + path;
            Win32Program item     = Win32Program.GetAppFromPath(fullPath);

            win32ProgramRepository.Add(item);

            // Act
            _fileSystemMocks[0].Raise(m => m.Deleted += null, e);

            // Assert
            Assert.AreEqual(0, win32ProgramRepository.Count());
        }
示例#14
0
        private static Win32Program InternetShortcutProgram(string path)
        {
            try
            {
                string[] lines    = FileWrapper.ReadAllLines(path);
                string   iconPath = string.Empty;
                string   urlPath  = string.Empty;
                bool     validApp = false;

                Regex internetShortcutURLPrefixes = new Regex(@"^steam:\/\/(rungameid|run)\/|^com\.epicgames\.launcher:\/\/apps\/");

                const string urlPrefix      = "URL=";
                const string iconFilePrefix = "IconFile=";

                foreach (string line in lines)
                {
                    // Using OrdinalIgnoreCase since this is used internally
                    if (line.StartsWith(urlPrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        urlPath = line.Substring(urlPrefix.Length);

                        try
                        {
                            Uri uri = new Uri(urlPath);
                        }
                        catch (UriFormatException e)
                        {
                            // To catch the exception if the uri cannot be parsed.
                            // Link to watson crash: https://watsonportal.microsoft.com/Failure?FailureSearchText=5f871ea7-e886-911f-1b31-131f63f6655b
                            ProgramLogger.Exception($"url could not be parsed", e, MethodBase.GetCurrentMethod().DeclaringType, urlPath);
                            return(new Win32Program()
                            {
                                Valid = false, Enabled = false
                            });
                        }

                        // To filter out only those steam shortcuts which have 'run' or 'rungameid' as the hostname
                        if (internetShortcutURLPrefixes.Match(urlPath).Success)
                        {
                            validApp = true;
                        }
                    }

                    // Using OrdinalIgnoreCase since this is used internally
                    if (line.StartsWith(iconFilePrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        iconPath = line.Substring(iconFilePrefix.Length);
                    }
                }

                if (!validApp)
                {
                    return(new Win32Program()
                    {
                        Valid = false, Enabled = false
                    });
                }

                try
                {
                    var p = new Win32Program
                    {
                        Name             = Path.GetFileNameWithoutExtension(path),
                        ExecutableName   = Path.GetFileName(path),
                        IcoPath          = iconPath,
                        FullPath         = urlPath,
                        UniqueIdentifier = path,
                        ParentDirectory  = Directory.GetParent(path).FullName,
                        Valid            = true,
                        Enabled          = true,
                        AppType          = ApplicationType.InternetShortcutApplication,
                    };
                    return(p);
                }
                catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException)
                {
                    ProgramLogger.Exception($"|Permission denied when trying to load the program from {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);

                    return(new Win32Program()
                    {
                        Valid = false, Enabled = false
                    });
                }
            }
            catch (Exception e)
            {
                ProgramLogger.Exception($"|An unexpected error occurred in the calling method InternetShortcutProgram at {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);

                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }
        }
示例#15
0
        // This function filters Internet Shortcut programs
        private static Win32Program InternetShortcutProgram(string path)
        {
            string[] lines    = FileWrapper.ReadAllLines(path);
            string   appName  = string.Empty;
            string   iconPath = string.Empty;
            string   urlPath  = string.Empty;
            string   scheme   = string.Empty;
            bool     validApp = false;

            Regex InternetShortcutURLPrefixes = new Regex(@"^steam:\/\/(rungameid|run)\/|^com\.epicgames\.launcher:\/\/apps\/");

            const string urlPrefix      = "URL=";
            const string iconFilePrefix = "IconFile=";

            foreach (string line in lines)
            {
                if (line.StartsWith(urlPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    urlPath = line.Substring(urlPrefix.Length);
                    Uri uri = new Uri(urlPath);

                    // To filter out only those steam shortcuts which have 'run' or 'rungameid' as the hostname
                    if (InternetShortcutURLPrefixes.Match(urlPath).Success)
                    {
                        validApp = true;
                    }
                }

                if (line.StartsWith(iconFilePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    iconPath = line.Substring(iconFilePrefix.Length);
                }
            }

            if (!validApp)
            {
                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }

            try
            {
                var p = new Win32Program
                {
                    Name             = Path.GetFileNameWithoutExtension(path),
                    ExecutableName   = Path.GetFileName(path),
                    IcoPath          = iconPath,
                    FullPath         = urlPath,
                    UniqueIdentifier = path,
                    ParentDirectory  = Directory.GetParent(path).FullName,
                    Valid            = true,
                    Enabled          = true,
                    AppType          = (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION,
                };
                return(p);
            }
            catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException)
            {
                ProgramLogger.LogException(
                    $"|Win32|InternetShortcutProgram|{path}" +
                    $"|Permission denied when trying to load the program from {path}", e);

                return(new Win32Program()
                {
                    Valid = false, Enabled = false
                });
            }
        }