private static bool GetFolderSize(string path, IMainClass mc, ref long cs, ref long files, ref long folders, ref DateTime ld, long delay) { try { if (cancelCalc) { return(false); } if (Filesystem.FileExists(path)) { cs += GetFileSize(path); files++; DateTime nw = DateTime.Now; if ((nw - ld).TotalMilliseconds > delay) { ld = nw; if (cancelCalc) { return(false); } new SetMCOutputLabelTextDel(SetMCOutputLabelText).BeginInvoke(mc, cs, files, folders, currentEnding, null, null); } return(true); } folders++; string[] itms = DirList2(path); if (itms == null || itms.Length <= 0 || cancelCalc) { return(false); } foreach (string itm in itms) { if (cancelCalc) { return(false); } GetFolderSize(itm, mc, ref cs, ref files, ref folders, ref ld, delay); } return(true); } catch { } return(false); }
public bool FileExists(string path) { return(Filesystem.FileExists(Path.Combine(BasePath, path))); }
public Task CreateShortcutsForExecutableAsync(SnapOsShortcutDescription shortcutDescription, ILog logger = null, CancellationToken cancellationToken = default) { if (shortcutDescription == null) { throw new ArgumentNullException(nameof(shortcutDescription)); } var baseDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath); var exeName = Filesystem.PathGetFileName(shortcutDescription.ExeAbsolutePath); var packageTitle = shortcutDescription.NuspecReader.GetTitle(); var authors = shortcutDescription.NuspecReader.GetAuthors(); var packageId = shortcutDescription.NuspecReader.GetIdentity().Id; var packageVersion = shortcutDescription.NuspecReader.GetIdentity().Version; var packageDescription = shortcutDescription.NuspecReader.GetDescription(); string LinkTargetForVersionInfo(SnapShortcutLocation location, FileVersionInfo versionInfo) { var possibleProductNames = new[] { versionInfo.ProductName, packageTitle, versionInfo.FileDescription, Filesystem.PathGetFileNameWithoutExtension(versionInfo.FileName) }; var possibleCompanyNames = new[] { versionInfo.CompanyName, authors ?? packageId }; var productName = possibleCompanyNames.First(x => !string.IsNullOrWhiteSpace(x)); var packageName = possibleProductNames.First(x => !string.IsNullOrWhiteSpace(x)); return(GetLinkTarget(location, packageName, productName)); } string GetLinkTarget(SnapShortcutLocation location, string title, string applicationName, bool createDirectoryIfNecessary = true) { var targetDirectory = location switch { SnapShortcutLocation.Desktop => SpecialFolders.DesktopDirectory, SnapShortcutLocation.StartMenu => Filesystem.PathCombine(SpecialFolders.StartMenu, "Programs", applicationName), SnapShortcutLocation.Startup => SpecialFolders.StartupDirectory, _ => throw new ArgumentOutOfRangeException(nameof(location), location, null) }; if (createDirectoryIfNecessary) { Filesystem.DirectoryCreateIfNotExists(targetDirectory); } return(Filesystem.PathCombine(targetDirectory, title + ".lnk")); } logger?.Info($"About to create shortcuts for {exeName}, base directory {baseDirectory}"); var fileVerInfo = FileVersionInfo.GetVersionInfo(shortcutDescription.ExeAbsolutePath); foreach (var flag in (SnapShortcutLocation[])Enum.GetValues(typeof(SnapShortcutLocation))) { if (!shortcutDescription.ShortcutLocations.HasFlag(flag)) { continue; } var file = LinkTargetForVersionInfo(flag, fileVerInfo); var fileExists = Filesystem.FileExists(file); // NB: If we've already installed the app, but the shortcut // is no longer there, we have to assume that the user didn't // want it there and explicitly deleted it, so we shouldn't // annoy them by recreating it. if (!fileExists && shortcutDescription.UpdateOnly) { logger?.Warn($"Wanted to update shortcut {file} but it appears user deleted it"); continue; } logger?.Info($"Creating shortcut for {exeName} => {file}"); ShellLink shellLink; logger?.ErrorIfThrows(() => SnapUtility.Retry(() => { Filesystem.FileDelete(file); shellLink = new ShellLink { Target = shortcutDescription.ExeAbsolutePath, IconPath = shortcutDescription.IconAbsolutePath ?? shortcutDescription.ExeAbsolutePath, IconIndex = 0, WorkingDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath), Description = packageDescription }; if (!string.IsNullOrWhiteSpace(shortcutDescription.ExeProgramArguments)) { shellLink.Arguments += $" -a \"{shortcutDescription.ExeProgramArguments}\""; } var appUserModelId = $"com.snap.{packageId.Replace(" ", "")}.{exeName.Replace(".exe", string.Empty).Replace(" ", string.Empty)}"; var toastActivatorClsid = SnapUtility.CreateGuidFromHash(appUserModelId).ToString(); shellLink.SetAppUserModelId(appUserModelId); shellLink.SetToastActivatorCLSID(toastActivatorClsid); logger.Info($"Saving shortcut: {file}. " + $"Target: {shellLink.Target}. " + $"Working directory: {shellLink.WorkingDirectory}. " + $"Arguments: {shellLink.Arguments}. " + $"ToastActivatorCSLID: {toastActivatorClsid}."); if (_isUnitTest == false) { shellLink.Save(file); } }, 4), $"Can't write shortcut: {file}"); } FixPinnedExecutables(baseDirectory, packageVersion, logger: logger); return(Task.CompletedTask); } void FixPinnedExecutables(string baseDirectory, SemanticVersion newCurrentVersion, bool removeAll = false, ILog logger = null) { if (Environment.OSVersion.Version < new Version(6, 1)) { logger?.Warn($"fixPinnedExecutables: Found OS Version '{Environment.OSVersion.VersionString}', exiting"); return; } var newCurrentFolder = "app-" + newCurrentVersion; var newAppPath = Filesystem.PathCombine(baseDirectory, newCurrentFolder); var taskbarPath = Filesystem.PathCombine(SpecialFolders.ApplicationData, "Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"); if (!Filesystem.DirectoryExists(taskbarPath)) { logger?.Info("fixPinnedExecutables: PinnedExecutables directory doesn't exist, skipping"); return; } var resolveLink = new Func <FileInfo, ShellLink>(file => { try { logger?.Debug("Examining Pin: " + file); return(new ShellLink(file.FullName)); } catch (Exception ex) { var message = $"File '{file.FullName}' could not be converted into a valid ShellLink"; logger?.WarnException(message, ex); return(null); } }); var shellLinks = new DirectoryInfo(taskbarPath).GetFiles("*.lnk").Select(resolveLink).ToArray(); foreach (var shortcut in shellLinks) { try { if (shortcut == null) { continue; } if (string.IsNullOrWhiteSpace(shortcut.Target)) { continue; } if (!shortcut.Target.StartsWith(baseDirectory, StringComparison.OrdinalIgnoreCase)) { continue; } if (removeAll) { Filesystem.FileDeleteWithRetries(shortcut.ShortCutFile); } else { UpdateShellLink(baseDirectory, shortcut, newAppPath, logger); } } catch (Exception ex) { var message = $"fixPinnedExecutables: shortcut failed: {shortcut?.Target}"; logger?.ErrorException(message, ex); } } } void UpdateShellLink([JetBrains.Annotations.NotNull] string baseDirectory, [JetBrains.Annotations.NotNull] ShellLink shortcut, [JetBrains.Annotations.NotNull] string newAppPath, ILog logger = null)
public Task CreateShortcutsForExecutableAsync(SnapOsShortcutDescription shortcutDescription, ILog logger = null, CancellationToken cancellationToken = default) { if (shortcutDescription == null) { throw new ArgumentNullException(nameof(shortcutDescription)); } var baseDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath); var exeName = Filesystem.PathGetFileName(shortcutDescription.ExeAbsolutePath); var packageTitle = shortcutDescription.NuspecReader.GetTitle(); var authors = shortcutDescription.NuspecReader.GetAuthors(); var packageId = shortcutDescription.NuspecReader.GetIdentity().Id; var packageVersion = shortcutDescription.NuspecReader.GetIdentity().Version; var packageDescription = shortcutDescription.NuspecReader.GetDescription(); string LinkTargetForVersionInfo(SnapShortcutLocation location, FileVersionInfo versionInfo) { var possibleProductNames = new[] { versionInfo.ProductName, packageTitle, versionInfo.FileDescription, Filesystem.PathGetFileNameWithoutExtension(versionInfo.FileName) }; var possibleCompanyNames = new[] { versionInfo.CompanyName, authors ?? packageId }; var productName = possibleCompanyNames.First(x => !string.IsNullOrWhiteSpace(x)); var packageName = possibleProductNames.First(x => !string.IsNullOrWhiteSpace(x)); return(GetLinkTarget(location, packageName, productName)); } string GetLinkTarget(SnapShortcutLocation location, string title, string applicationName, bool createDirectoryIfNecessary = true) { string targetDirectory; switch (location) { case SnapShortcutLocation.Desktop: targetDirectory = SpecialFolders.DesktopDirectory; break; case SnapShortcutLocation.StartMenu: targetDirectory = Filesystem.PathCombine(SpecialFolders.StartMenu, "Programs", applicationName); break; case SnapShortcutLocation.Startup: targetDirectory = SpecialFolders.StartupDirectory; break; default: throw new ArgumentOutOfRangeException(nameof(location), location, null); } if (createDirectoryIfNecessary) { Filesystem.DirectoryCreateIfNotExists(targetDirectory); } return(Filesystem.PathCombine(targetDirectory, title + ".lnk")); } logger?.Info("About to create shortcuts for {0}, base directory {1}", exeName, baseDirectory); var fileVerInfo = FileVersionInfo.GetVersionInfo(shortcutDescription.ExeAbsolutePath); foreach (var flag in (SnapShortcutLocation[])Enum.GetValues(typeof(SnapShortcutLocation))) { if (!shortcutDescription.ShortcutLocations.HasFlag(flag)) { continue; } var file = LinkTargetForVersionInfo(flag, fileVerInfo); var fileExists = Filesystem.FileExists(file); // NB: If we've already installed the app, but the shortcut // is no longer there, we have to assume that the user didn't // want it there and explicitly deleted it, so we shouldn't // annoy them by recreating it. if (!fileExists && shortcutDescription.UpdateOnly) { logger?.Warn("Wanted to update shortcut {0} but it appears user deleted it", file); continue; } logger?.Info("Creating shortcut for {0} => {1}", exeName, file); ShellLink shellLink; logger?.ErrorIfThrows(() => SnapUtility.Retry(() => { Filesystem.FileDelete(file); shellLink = new ShellLink { Target = shortcutDescription.ExeAbsolutePath, IconPath = shortcutDescription.IconAbsolutePath ?? shortcutDescription.ExeAbsolutePath, IconIndex = 0, WorkingDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath), Description = packageDescription }; if (!string.IsNullOrWhiteSpace(shortcutDescription.ExeProgramArguments)) { shellLink.Arguments += $" -a \"{shortcutDescription.ExeProgramArguments}\""; } var appUserModelId = $"com.snap.{packageId.Replace(" ", "")}.{exeName.Replace(".exe", string.Empty).Replace(" ", string.Empty)}"; var toastActivatorClsid = SnapUtility.CreateGuidFromHash(appUserModelId).ToString(); shellLink.SetAppUserModelId(appUserModelId); shellLink.SetToastActivatorCLSID(toastActivatorClsid); logger.Info($"Saving shortcut: {file}. " + $"Target: {shellLink.Target}. " + $"Working directory: {shellLink.WorkingDirectory}. " + $"Arguments: {shellLink.Arguments}. " + $"ToastActivatorCSLID: {toastActivatorClsid}."); if (_isUnitTest == false) { shellLink.Save(file); } }, 4), $"Can't write shortcut: {file}"); } FixPinnedExecutables(baseDirectory, packageVersion, logger: logger); return(Task.CompletedTask); }
public static IPackReader CreatePackReader(string archivePath) { if (Filesystem.DirectoryExists(archivePath)) { return(new DirectoryPackReader(archivePath)); } else if (archivePath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) && Filesystem.FileExists(archivePath)) { return(new ZipPackReader(archivePath)); } else { throw new FormatException("Unknown resource pack type"); } }