private static Win32 LnkProgram(string path) { var program = Win32Program(path); try { var link = new ShellLink(); const uint STGM_READ = 0; ((IPersistFile)link).Load(path, STGM_READ); var hwnd = new _RemotableHandle(); link.Resolve(ref hwnd, 0); const int MAX_PATH = 260; StringBuilder buffer = new StringBuilder(MAX_PATH); var data = new _WIN32_FIND_DATAW(); const uint SLGP_SHORTPATH = 1; link.GetPath(buffer, buffer.Capacity, ref data, SLGP_SHORTPATH); var target = buffer.ToString(); if (!string.IsNullOrEmpty(target)) { var extension = Extension(target); if (extension == ExeExtension && File.Exists(target)) { buffer = new StringBuilder(MAX_PATH); link.GetDescription(buffer, MAX_PATH); var description = buffer.ToString(); if (!string.IsNullOrEmpty(description)) { program.Description = description; } else { var info = FileVersionInfo.GetVersionInfo(target); if (!string.IsNullOrEmpty(info.FileDescription)) { program.Description = info.FileDescription; } } } } return(program); } catch (COMException e) { // C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MiracastView.lnk always cause exception ProgramLogger.LogException($"|Win32|LnkProgram|{path}" + "|Error caused likely due to trying to get the description of the program", e); program.Valid = false; return(program); } #if !DEBUG //Only do a catch all in production. This is so make developer aware of any unhandled exception and add the exception handling in. catch (Exception e) { ProgramLogger.LogException($"|Win32|LnkProgram|{path}" + "|An unexpected error occurred in the calling method LnkProgram", e); program.Valid = false; return(program); } #endif }
// This function filters Internet Shortcut programs private static Win32 InternetShortcutProgram(string path) { string[] lines = System.IO.File.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)) { 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)) { iconPath = line.Substring(iconFilePrefix.Length); } } if (!validApp) { return(new Win32() { Valid = false, Enabled = false }); } try { var p = new Win32 { 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 Win32() { Valid = false, Enabled = false }); } }
internal string ResourceFromPri(string packageFullName, string resourceReference) { const string prefix = "ms-resource:"; if (!string.IsNullOrWhiteSpace(resourceReference) && resourceReference.StartsWith(prefix)) { // magic comes from @talynone // https://github.com/talynone/Wox.Plugin.WindowsUniversalAppLauncher/blob/master/StoreAppLauncher/Helpers/NativeApiHelper.cs#L139-L153 string key = resourceReference.Substring(prefix.Length); string parsed; if (key.StartsWith("//")) { parsed = prefix + key; } else if (key.StartsWith("/")) { parsed = prefix + "//" + key; } else if (key.Contains("resources", StringComparison.OrdinalIgnoreCase)) { parsed = prefix + key; } else { parsed = prefix + "///resources/" + key; } var outBuffer = new StringBuilder(128); string source = $"@{{{packageFullName}? {parsed}}}"; var capacity = (uint)outBuffer.Capacity; var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero); if (hResult == Hresult.Ok) { var loaded = outBuffer.ToString(); if (!string.IsNullOrEmpty(loaded)) { return(loaded); } else { ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result " + $"pri {source} in uwp location {Package.Location}", new NullReferenceException()); return(string.Empty); } } else { // https://github.com/Wox-launcher/Wox/issues/964 // known hresult 2147942522: // 'Microsoft Corporation' violates pattern constraint of '\bms-resource:.{1,256}'. // for // Microsoft.MicrosoftOfficeHub_17.7608.23501.0_x64__8wekyb3d8bbwe: ms-resource://Microsoft.MicrosoftOfficeHub/officehubintl/AppManifest_GetOffice_Description // Microsoft.BingFoodAndDrink_3.0.4.336_x64__8wekyb3d8bbwe: ms-resource:AppDescription var e = Marshal.GetExceptionForHR((int)hResult); ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Load pri failed {source} with HResult {hResult} and location {Package.Location}", e); return(string.Empty); } } else { return(resourceReference); } }
internal string LogoPathFromUri(string uri, string theme) { // all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets // windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx // windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size // windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx string path; if (uri.Contains("\\")) { path = Path.Combine(Package.Location, uri); } else { // for C:\Windows\MiracastView etc path = Path.Combine(Package.Location, "Assets", uri); } var extension = Path.GetExtension(path); if (extension != null) { var end = path.Length - extension.Length; var prefix = path.Substring(0, end); var paths = new List <string> { path }; var scaleFactors = new Dictionary <PackageVersion, List <int> > { // scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables, { PackageVersion.Windows10, new List <int> { 100, 125, 150, 200, 400 } }, { PackageVersion.Windows81, new List <int> { 100, 120, 140, 160, 180 } }, { PackageVersion.Windows8, new List <int> { 100 } } }; if (scaleFactors.ContainsKey(Package.Version)) { foreach (var factor in scaleFactors[Package.Version]) { paths.Add($"{prefix}.scale-{factor}{extension}"); paths.Add($"{prefix}.scale-{factor}_{theme}{extension}"); paths.Add($"{prefix}.{theme}_scale-{factor}{extension}"); } } paths = paths.OrderByDescending(x => x.Contains(theme)).ToList(); var selected = paths.FirstOrDefault(File.Exists); if (!string.IsNullOrEmpty(selected)) { return(selected); } else { int appIconSize = 36; var targetSizes = new List <int> { 16, 24, 30, 36, 44, 60, 72, 96, 128, 180, 256 }.AsParallel(); Dictionary <string, int> pathFactorPairs = new Dictionary <string, int>(); foreach (var factor in targetSizes) { string simplePath = $"{prefix}.targetsize-{factor}{extension}"; string suffixThemePath = $"{prefix}.targetsize-{factor}_{theme}{extension}"; string prefixThemePath = $"{prefix}.{theme}_targetsize-{factor}{extension}"; paths.Add(simplePath); paths.Add(suffixThemePath); paths.Add(prefixThemePath); pathFactorPairs.Add(simplePath, factor); pathFactorPairs.Add(suffixThemePath, factor); pathFactorPairs.Add(prefixThemePath, factor); } paths = paths.OrderByDescending(x => x.Contains(theme)).ToList(); var selectedIconPath = paths.OrderBy(x => Math.Abs(pathFactorPairs.GetValueOrDefault(x) - appIconSize)).FirstOrDefault(File.Exists); if (!string.IsNullOrEmpty(selectedIconPath)) { return(selectedIconPath); } else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + $"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException()); return(string.Empty); } } } else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + $"|Unable to find extension from {uri} for {UserModelId} " + $"in package location {Package.Location}", new FileNotFoundException()); return(string.Empty); } }
private static IEnumerable <string> ProgramPaths(string directory, IList <string> suffixes, bool recursiveSearch = true) { if (!Directory.Exists(directory)) { return(Array.Empty <string>()); } var files = new List <string>(); var folderQueue = new Queue <string>(); folderQueue.Enqueue(directory); do { var currentDirectory = folderQueue.Dequeue(); try { foreach (var suffix in suffixes) { try { files.AddRange(Directory.EnumerateFiles(currentDirectory, $"*.{suffix}", SearchOption.TopDirectoryOnly)); } catch (DirectoryNotFoundException e) { ProgramLogger.LogException( $"|Win32|ProgramPaths|{currentDirectory}" + "|The directory trying to load the program from does not exist", e); } } } catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException) { ProgramLogger.LogException( $"|Win32|ProgramPaths|{currentDirectory}" + $"|Permission denied when trying to load programs from {currentDirectory}", e); } try { // If the search is set to be non-recursive, then do not enqueue the child directories. if (!recursiveSearch) { continue; } foreach (var childDirectory in Directory.EnumerateDirectories(currentDirectory, "*", SearchOption.TopDirectoryOnly)) { folderQueue.Enqueue(childDirectory); } } catch (Exception e) when(e is SecurityException || e is UnauthorizedAccessException) { ProgramLogger.LogException( $"|Win32|ProgramPaths|{currentDirectory}" + $"|Permission denied when trying to load programs from {currentDirectory}", e); } }while (folderQueue.Any()); return(files); }
internal string LogoPathFromUri(string uri) { // all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets // windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx // windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size // windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx string path; if (uri.Contains("\\")) { path = Path.Combine(Package.Location, uri); } else { // for C:\Windows\MiracastView etc path = Path.Combine(Package.Location, "Assets", uri); } var extension = Path.GetExtension(path); if (extension != null) { var end = path.Length - extension.Length; var prefix = path.Substring(0, end); var paths = new List <string> { path }; var scaleFactors = new Dictionary <PackageVersion, List <int> > { // scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables, { PackageVersion.Windows10, new List <int> { 100, 125, 150, 200, 400 } }, { PackageVersion.Windows81, new List <int> { 100, 120, 140, 160, 180 } }, { PackageVersion.Windows8, new List <int> { 100 } } }; if (scaleFactors.ContainsKey(Package.Version)) { foreach (var factor in scaleFactors[Package.Version]) { paths.Add($"{prefix}.scale-{factor}{extension}"); } } var selected = paths.FirstOrDefault(File.Exists); if (!string.IsNullOrEmpty(selected)) { return(selected); } else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + $"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException()); return(string.Empty); } } else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + $"|Unable to find extension from {uri} for {UserModelId} " + $"in package location {Package.Location}", new FileNotFoundException()); return(string.Empty); } }
// This function filters Internet Shortcut programs private static Win32Program InternetShortcutProgram(string path) { 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) { 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.LogException($"|Win32Program|InternetShortcutProgram|{urlPath}|url could not be parsed", e); 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; } } 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.LogException( $"|Win32|InternetShortcutProgram|{path}" + $"|Permission denied when trying to load the program from {path}", e); return(new Win32Program() { Valid = false, Enabled = false }); } }
// This function filters Internet Shortcut programs private static Win32 InternetShortcutProgram(string path) { string[] lines = System.IO.File.ReadAllLines(path); string appName = string.Empty; string iconPath = string.Empty; string scheme = string.Empty; bool validApp = false; const string steamScheme = "steam"; const string urlPrefix = "URL="; const string iconFilePrefix = "IconFile="; const string hostnameRun = "run"; const string hostnameRunGameId = "rungameid"; foreach (string line in lines) { if (line.StartsWith(urlPrefix)) { var 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 (uri.Scheme.Equals(steamScheme, StringComparison.OrdinalIgnoreCase) && (uri.Host.Equals(hostnameRun, StringComparison.OrdinalIgnoreCase) || uri.Host.Equals(hostnameRunGameId, StringComparison.OrdinalIgnoreCase))) { validApp = true; } } if (line.StartsWith(iconFilePrefix)) { iconPath = line.Substring(iconFilePrefix.Length); } } if (!validApp) { return(new Win32() { Valid = false, Enabled = false }); } try { var p = new Win32 { Name = Path.GetFileNameWithoutExtension(path), ExecutableName = Path.GetFileName(path), IcoPath = iconPath, FullPath = path.ToLower(), UniqueIdentifier = path, ParentDirectory = Directory.GetParent(path).FullName, Description = InternetShortcutApplication, Valid = true, Enabled = true, AppType = InternetShortcutApplication }; 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 Win32() { Valid = false, Enabled = false }); } }
private ImageSource PlatedImage(BitmapImage image) { if (!string.IsNullOrEmpty(BackgroundColor)) { string currentBackgroundColor; if (BackgroundColor == "transparent") { currentBackgroundColor = SystemParameters.WindowGlassBrush.ToString(CultureInfo.InvariantCulture); } else { currentBackgroundColor = BackgroundColor; } var padding = 8; var width = image.Width + (2 * padding); var height = image.Height + (2 * padding); var x = 0; var y = 0; var group = new DrawingGroup(); var converted = ColorConverter.ConvertFromString(currentBackgroundColor); if (converted != null) { var color = (Color)converted; var brush = new SolidColorBrush(color); var pen = new Pen(brush, 1); var backgroundArea = new Rect(0, 0, width, height); var rectangleGeometry = new RectangleGeometry(backgroundArea); var rectDrawing = new GeometryDrawing(brush, pen, rectangleGeometry); group.Children.Add(rectDrawing); var imageArea = new Rect(x + padding, y + padding, image.Width, image.Height); var imageDrawing = new ImageDrawing(image, imageArea); group.Children.Add(imageDrawing); // http://stackoverflow.com/questions/6676072/get-system-drawing-bitmap-of-a-wpf-area-using-visualbrush var visual = new DrawingVisual(); var context = visual.RenderOpen(); context.DrawDrawing(group); context.Close(); const int dpiScale100 = 96; var bitmap = new RenderTargetBitmap( Convert.ToInt32(width), Convert.ToInt32(height), dpiScale100, dpiScale100, PixelFormats.Pbgra32); bitmap.Render(visual); return(bitmap); } else { ProgramLogger.LogException( $"|UWP|PlatedImage|{Package.Location}|Unable to convert background string {BackgroundColor} " + $"to color for {Package.Location}", new InvalidOperationException()); return(new BitmapImage(new Uri(Constant.ErrorIcon))); } } else { // todo use windows theme as background return(image); } }