mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-24 20:46:20 +08:00
[Launcher] Categorize Lnk files in program plugin correctly as per the target file type (#6348)
* Updated UnregisteredApps code * Added file type checking code and Folder and File classifications * Added more file formats * Removed run as admin for lnk folders * Added script files as executable and changed hashset to case insensitive * Removed runasadmin for generic files * Removed FileTypes enum * Extended ApplicationTypes enum * Fix file format error * Cleaned use of ApplicationType enum to public and match AppType and used ApplicationType in OnAppRenamed * Modify tests to use ApplicationType enum * Added tests for new App types * Modified dummy appref * Mock Directory.Exists and add tests for GetAppTypeFromPath * Combined tests
This commit is contained in:
parent
ab8bec8866
commit
82e1be2839
@ -8,6 +8,7 @@ using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.FileSystemHelper;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
@ -23,7 +24,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "notepad.exe",
|
||||
FullPath = "c:\\windows\\system32\\notepad.exe",
|
||||
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _notepadUsers = new Win32Program
|
||||
@ -32,7 +33,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "notepad.exe",
|
||||
FullPath = "c:\\windows\\system32\\notepad.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _azureCommandPrompt = new Win32Program
|
||||
@ -41,7 +42,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "cmd.exe",
|
||||
FullPath = "c:\\windows\\system32\\cmd.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\microsoft azure\\microsoft azure sdk for .net\\v2.9\\microsoft azure command prompt - v2.9.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _visualStudioCommandPrompt = new Win32Program
|
||||
@ -50,7 +51,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "cmd.exe",
|
||||
FullPath = "c:\\windows\\system32\\cmd.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\visual studio 2019\\visual studio tools\\vc\\x64 native tools command prompt for vs 2019.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _commandPrompt = new Win32Program
|
||||
@ -59,7 +60,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "cmd.exe",
|
||||
FullPath = "c:\\windows\\system32\\cmd.exe",
|
||||
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\command prompt.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _fileExplorer = new Win32Program
|
||||
@ -68,7 +69,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "File Explorer.lnk",
|
||||
FullPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\file explorer.lnk",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _wordpad = new Win32Program
|
||||
@ -77,7 +78,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "wordpad.exe",
|
||||
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\wordpad.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _wordpadDuplicate = new Win32Program
|
||||
@ -86,7 +87,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "WORDPAD.EXE",
|
||||
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _twitterChromePwa = new Win32Program
|
||||
@ -122,7 +123,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "msedge.exe",
|
||||
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\msedge.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\microsoft edge.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _chrome = new Win32Program
|
||||
@ -131,7 +132,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "chrome.exe",
|
||||
FullPath = "c:\\program files (x86)\\google\\chrome\\application\\chrome.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\google chrome.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyProxyApp = new Win32Program
|
||||
@ -140,7 +141,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "test_proxy.exe",
|
||||
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\test_proxy.exe",
|
||||
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\test proxy.lnk",
|
||||
AppType = 2,
|
||||
AppType = Win32Program.ApplicationType.Win32Application,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _cmdRunCommand = new Win32Program
|
||||
@ -149,7 +150,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "cmd.exe",
|
||||
FullPath = "c:\\windows\\system32\\cmd.exe",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 3, // Run command
|
||||
AppType = Win32Program.ApplicationType.RunCommand, // Run command
|
||||
};
|
||||
|
||||
private static readonly Win32Program _cmderRunCommand = new Win32Program
|
||||
@ -159,7 +160,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
ExecutableName = "Cmder.exe",
|
||||
FullPath = "c:\\tools\\cmder\\cmder.exe",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 3, // Run command
|
||||
AppType = Win32Program.ApplicationType.RunCommand, // Run command
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyInternetShortcutApp = new Win32Program
|
||||
@ -169,7 +170,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
FullPath = "steam://rungameid/1258080",
|
||||
ParentDirectory = "C:\\Users\\temp\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Steam",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 1,
|
||||
AppType = Win32Program.ApplicationType.InternetShortcutApplication,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyInternetShortcutAppDuplicate = new Win32Program
|
||||
@ -179,9 +180,59 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
FullPath = "steam://rungameid/1258080",
|
||||
ParentDirectory = "C:\\Users\\temp\\Desktop",
|
||||
LnkResolvedPath = null,
|
||||
AppType = 1,
|
||||
AppType = Win32Program.ApplicationType.InternetShortcutApplication,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyAppRefApp = new Win32Program
|
||||
{
|
||||
Name = "Dummy AppRef Application",
|
||||
ExecutableName = "dummy.appref-ms",
|
||||
FullPath = "C:\\dummy.appref-ms",
|
||||
ParentDirectory = "C:\\",
|
||||
LnkResolvedPath = null,
|
||||
AppType = Win32Program.ApplicationType.ApprefApplication,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyShortcutApp = new Win32Program
|
||||
{
|
||||
Name = "Dummy Shortcut Application",
|
||||
ExecutableName = "application.lnk",
|
||||
FullPath = "C:\\application.lnk",
|
||||
ParentDirectory = "C:\\",
|
||||
LnkResolvedPath = "C:\\application.lnk",
|
||||
AppType = Win32Program.ApplicationType.ShortcutApplication,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyFolderApp = new Win32Program
|
||||
{
|
||||
Name = "Dummy Folder",
|
||||
ExecutableName = "application.lnk",
|
||||
FullPath = "C:\\dummy\\folder",
|
||||
ParentDirectory = "C:\\dummy\\",
|
||||
LnkResolvedPath = "C:\\tools\\application.lnk",
|
||||
AppType = Win32Program.ApplicationType.Folder,
|
||||
};
|
||||
|
||||
private static readonly Win32Program _dummyGenericFileApp = new Win32Program
|
||||
{
|
||||
Name = "Dummy Folder",
|
||||
ExecutableName = "application.lnk",
|
||||
FullPath = "C:\\dummy\\file.pdf",
|
||||
ParentDirectory = "C:\\dummy\\",
|
||||
LnkResolvedPath = "C:\\tools\\application.lnk",
|
||||
AppType = Win32Program.ApplicationType.GenericFile,
|
||||
};
|
||||
|
||||
private static IDirectoryWrapper GetMockedDirectoryWrapper()
|
||||
{
|
||||
var mockDirectory = new Mock<IDirectoryWrapper>();
|
||||
|
||||
// Check if the file has no extension. This is not actually true since there can be files without extensions, but this is sufficient for the purpose of a mock function
|
||||
Func<string, bool> returnValue = arg => string.IsNullOrEmpty(System.IO.Path.GetExtension(arg));
|
||||
mockDirectory.Setup(m => m.Exists(It.IsAny<string>())).Returns(returnValue);
|
||||
return mockDirectory.Object;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DedupFunctionWhenCalledMustRemoveDuplicateNotepads()
|
||||
{
|
||||
@ -427,6 +478,68 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
Assert.AreEqual(contextMenuResults[2].Title, Properties.Resources.wox_plugin_program_open_in_console);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AppRefApplicationShouldReturnContextMenuWithOpenInConsoleWhenContextMenusIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var mock = new Mock<IPublicAPI>();
|
||||
|
||||
// Act
|
||||
List<ContextMenuResult> contextMenuResults = _dummyAppRefApp.ContextMenus(mock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(contextMenuResults.Count, 3);
|
||||
Assert.AreEqual(contextMenuResults[0].Title, Properties.Resources.wox_plugin_program_run_as_administrator);
|
||||
Assert.AreEqual(contextMenuResults[1].Title, Properties.Resources.wox_plugin_program_open_containing_folder);
|
||||
Assert.AreEqual(contextMenuResults[2].Title, Properties.Resources.wox_plugin_program_open_in_console);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShortcutApplicationShouldReturnContextMenuWithOpenInConsoleWhenContextMenusIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var mock = new Mock<IPublicAPI>();
|
||||
|
||||
// Act
|
||||
List<ContextMenuResult> contextMenuResults = _dummyShortcutApp.ContextMenus(mock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(contextMenuResults.Count, 3);
|
||||
Assert.AreEqual(contextMenuResults[0].Title, Properties.Resources.wox_plugin_program_run_as_administrator);
|
||||
Assert.AreEqual(contextMenuResults[1].Title, Properties.Resources.wox_plugin_program_open_containing_folder);
|
||||
Assert.AreEqual(contextMenuResults[2].Title, Properties.Resources.wox_plugin_program_open_in_console);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FolderApplicationShouldReturnContextMenuWithOpenInConsoleWhenContextMenusIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var mock = new Mock<IPublicAPI>();
|
||||
|
||||
// Act
|
||||
List<ContextMenuResult> contextMenuResults = _dummyFolderApp.ContextMenus(mock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(contextMenuResults.Count, 2);
|
||||
Assert.AreEqual(contextMenuResults[0].Title, Properties.Resources.wox_plugin_program_open_containing_folder);
|
||||
Assert.AreEqual(contextMenuResults[1].Title, Properties.Resources.wox_plugin_program_open_in_console);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenericFileApplicationShouldReturnContextMenuWithOpenInConsoleWhenContextMenusIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var mock = new Mock<IPublicAPI>();
|
||||
|
||||
// Act
|
||||
List<ContextMenuResult> contextMenuResults = _dummyGenericFileApp.ContextMenus(mock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(contextMenuResults.Count, 2);
|
||||
Assert.AreEqual(contextMenuResults[0].Title, Properties.Resources.wox_plugin_program_open_containing_folder);
|
||||
Assert.AreEqual(contextMenuResults[1].Title, Properties.Resources.wox_plugin_program_open_in_console);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Win32AppsShouldSetNameAsTitleWhileCreatingResult()
|
||||
{
|
||||
@ -440,5 +553,21 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
||||
Assert.IsTrue(result.Title.Equals(_cmderRunCommand.Name, StringComparison.Ordinal));
|
||||
Assert.IsFalse(result.Title.Equals(_cmderRunCommand.Description, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[TestCase("C:\\Program Files\\dummy.exe", ExpectedResult = Win32Program.ApplicationType.Win32Application)]
|
||||
[TestCase("C:\\Program Files\\dummy.msc", ExpectedResult = Win32Program.ApplicationType.Win32Application)]
|
||||
[TestCase("C:\\Program Files\\dummy.lnk", ExpectedResult = Win32Program.ApplicationType.ShortcutApplication)]
|
||||
[TestCase("C:\\Program Files\\dummy.appref-ms", ExpectedResult = Win32Program.ApplicationType.ApprefApplication)]
|
||||
[TestCase("C:\\Program Files\\dummy.url", ExpectedResult = Win32Program.ApplicationType.InternetShortcutApplication)]
|
||||
[TestCase("C:\\Program Files\\dummy", ExpectedResult = Win32Program.ApplicationType.Folder)]
|
||||
[TestCase("C:\\Program Files\\dummy.txt", ExpectedResult = Win32Program.ApplicationType.GenericFile)]
|
||||
public Win32Program.ApplicationType GetAppTypeFromPathShouldReturnCorrectAppTypeWhenAppPathIsPassedAsArgument(string path)
|
||||
{
|
||||
// Directory.Exists must be mocked
|
||||
Win32Program.DirectoryWrapper = GetMockedDirectoryWrapper();
|
||||
|
||||
// Act
|
||||
return Win32Program.GetAppTypeFromPath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(win32ProgramRepository.Count(), 1);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, 2);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.ApprefApplication);
|
||||
}
|
||||
|
||||
[TestCase("directory", "path.appref-ms")]
|
||||
@ -145,7 +145,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(win32ProgramRepository.Count(), 1);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, 2);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.Win32Application);
|
||||
}
|
||||
|
||||
[TestCase("directory", "path.exe")]
|
||||
@ -216,7 +216,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(win32ProgramRepository.Count(), 1);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, 1); // Internet Shortcut Application
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.InternetShortcutApplication); // Internet Shortcut Application
|
||||
}
|
||||
|
||||
[TestCase("path.url")]
|
||||
@ -336,7 +336,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(win32ProgramRepository.Count(), 1);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, 2);
|
||||
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.Win32Application);
|
||||
}
|
||||
|
||||
[TestCase("directory", "path.lnk")]
|
||||
|
@ -52,7 +52,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
public string Location => ParentDirectory;
|
||||
|
||||
public uint AppType { get; set; }
|
||||
public ApplicationType AppType { get; set; }
|
||||
|
||||
// Wrappers for File Operations
|
||||
public static IFileVersionInfoWrapper FileVersionInfoWrapper { get; set; } = new FileVersionInfoWrapper();
|
||||
@ -61,20 +61,26 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
public static IShellLinkHelper Helper { get; set; } = new ShellLinkHelper();
|
||||
|
||||
public static IDirectoryWrapper DirectoryWrapper { get; set; } = new DirectoryWrapper();
|
||||
|
||||
private const string ShortcutExtension = "lnk";
|
||||
private const string ApplicationReferenceExtension = "appref-ms";
|
||||
private const string ExeExtension = "exe";
|
||||
private const string InternetShortcutExtension = "url";
|
||||
private static readonly HashSet<string> ExecutableApplicationExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "exe", "bat", "bin", "com", "msc", "msi", "cmd", "ps1", "job", "msp", "mst", "sct", "ws", "wsh", "wsf" };
|
||||
|
||||
private const string ProxyWebApp = "_proxy.exe";
|
||||
private const string AppIdArgument = "--app-id";
|
||||
|
||||
private enum ApplicationTypes
|
||||
public enum ApplicationType
|
||||
{
|
||||
WEB_APPLICATION = 0,
|
||||
INTERNET_SHORTCUT_APPLICATION = 1,
|
||||
WIN32_APPLICATION = 2,
|
||||
RUN_COMMAND = 3,
|
||||
WebApplication = 0,
|
||||
InternetShortcutApplication = 1,
|
||||
Win32Application = 2,
|
||||
ShortcutApplication = 3,
|
||||
ApprefApplication = 4,
|
||||
RunCommand = 5,
|
||||
Folder = 6,
|
||||
GenericFile = 7,
|
||||
}
|
||||
|
||||
// Function to calculate the score of a result
|
||||
@ -106,7 +112,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
}
|
||||
|
||||
// Set the subtitle to 'Web Application'
|
||||
AppType = (uint)ApplicationTypes.WEB_APPLICATION;
|
||||
AppType = ApplicationType.WebApplication;
|
||||
|
||||
string[] subqueries = query?.Split() ?? Array.Empty<string>();
|
||||
bool nameContainsQuery = false;
|
||||
@ -132,22 +138,30 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
// Function to set the subtitle based on the Type of application
|
||||
private string SetSubtitle()
|
||||
{
|
||||
if (AppType == (uint)ApplicationTypes.WIN32_APPLICATION)
|
||||
if (AppType == ApplicationType.Win32Application || AppType == ApplicationType.ShortcutApplication || AppType == ApplicationType.ApprefApplication)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_win32_application;
|
||||
}
|
||||
else if (AppType == (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION)
|
||||
else if (AppType == ApplicationType.InternetShortcutApplication)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_internet_shortcut_application;
|
||||
}
|
||||
else if (AppType == (uint)ApplicationTypes.WEB_APPLICATION)
|
||||
else if (AppType == ApplicationType.WebApplication)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_web_application;
|
||||
}
|
||||
else if (AppType == (uint)ApplicationTypes.RUN_COMMAND)
|
||||
else if (AppType == ApplicationType.RunCommand)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_run_command;
|
||||
}
|
||||
else if (AppType == ApplicationType.Folder)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_folder_type;
|
||||
}
|
||||
else if (AppType == ApplicationType.GenericFile)
|
||||
{
|
||||
return Properties.Resources.powertoys_run_plugin_program_generic_file_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
@ -156,7 +170,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
public bool QueryEqualsNameForRunCommands(string query)
|
||||
{
|
||||
if (query != null && AppType == (uint)ApplicationTypes.RUN_COMMAND
|
||||
if (query != null && AppType == ApplicationType.RunCommand
|
||||
&& !query.Equals(Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
@ -240,7 +254,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
var contextMenus = new List<ContextMenuResult>();
|
||||
|
||||
if (AppType != (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION)
|
||||
if (AppType != ApplicationType.InternetShortcutApplication && AppType != ApplicationType.Folder && AppType != ApplicationType.GenericFile)
|
||||
{
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
@ -330,7 +344,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
Description = string.Empty,
|
||||
Valid = true,
|
||||
Enabled = true,
|
||||
AppType = (uint)ApplicationTypes.WIN32_APPLICATION,
|
||||
AppType = ApplicationType.Win32Application,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
@ -394,7 +408,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
ParentDirectory = Directory.GetParent(path).FullName,
|
||||
Valid = true,
|
||||
Enabled = true,
|
||||
AppType = (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION,
|
||||
AppType = ApplicationType.InternetShortcutApplication,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
@ -421,14 +435,11 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
if (!string.IsNullOrEmpty(target))
|
||||
{
|
||||
var extension = Extension(target);
|
||||
if (extension == ExeExtension && File.Exists(target))
|
||||
if (File.Exists(target) || Directory.Exists(target))
|
||||
{
|
||||
program.LnkResolvedPath = program.FullPath;
|
||||
program.FullPath = Path.GetFullPath(target).ToLower(CultureInfo.CurrentCulture);
|
||||
program.ExecutableName = Path.GetFileName(target);
|
||||
program.HasArguments = Helper.HasArguments;
|
||||
program.Arguments = Helper.Arguments;
|
||||
program.AppType = GetAppTypeFromPath(target);
|
||||
|
||||
var description = Helper.Description;
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
@ -494,6 +505,43 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
}
|
||||
}
|
||||
|
||||
// Function to get the application type, given the path to the application
|
||||
public static ApplicationType GetAppTypeFromPath(string path)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
}
|
||||
|
||||
string extension = Extension(path);
|
||||
ApplicationType appType = ApplicationType.GenericFile;
|
||||
|
||||
if (ExecutableApplicationExtensions.Contains(extension))
|
||||
{
|
||||
appType = ApplicationType.Win32Application;
|
||||
}
|
||||
else if (extension.Equals(ShortcutExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
appType = ApplicationType.ShortcutApplication;
|
||||
}
|
||||
else if (extension.Equals(ApplicationReferenceExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
appType = ApplicationType.ApprefApplication;
|
||||
}
|
||||
else if (extension.Equals(InternetShortcutExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
appType = ApplicationType.InternetShortcutApplication;
|
||||
}
|
||||
|
||||
// If the path exists, check if it is a directory
|
||||
else if (DirectoryWrapper.Exists(path))
|
||||
{
|
||||
appType = ApplicationType.Folder;
|
||||
}
|
||||
|
||||
return appType;
|
||||
}
|
||||
|
||||
// Function to get the Win32 application, given the path to the application
|
||||
public static Win32Program GetAppFromPath(string path)
|
||||
{
|
||||
@ -503,26 +551,23 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
}
|
||||
|
||||
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);
|
||||
ApplicationType appType = GetAppTypeFromPath(path);
|
||||
|
||||
if (extension.Equals(exeExtension, StringComparison.OrdinalIgnoreCase))
|
||||
if (appType == ApplicationType.Win32Application)
|
||||
{
|
||||
app = ExeProgram(path);
|
||||
}
|
||||
else if (extension.Equals(lnkExtension, StringComparison.OrdinalIgnoreCase))
|
||||
else if (appType == ApplicationType.ShortcutApplication)
|
||||
{
|
||||
app = LnkProgram(path);
|
||||
}
|
||||
else if (extension.Equals(apprefExtension, StringComparison.OrdinalIgnoreCase))
|
||||
else if (appType == ApplicationType.ApprefApplication)
|
||||
{
|
||||
app = CreateWin32Program(path);
|
||||
app.AppType = ApplicationType.ApprefApplication;
|
||||
}
|
||||
else if (extension.Equals(urlExtenion, StringComparison.OrdinalIgnoreCase))
|
||||
else if (appType == ApplicationType.InternetShortcutApplication)
|
||||
{
|
||||
app = InternetShortcutProgram(path);
|
||||
}
|
||||
@ -626,13 +671,13 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
var paths = listToAdd.Distinct().ToArray();
|
||||
|
||||
var programs1 = paths.AsParallel().Where(p => Extension(p) == ExeExtension).Select(ExeProgram);
|
||||
var programs2 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(ExeProgram);
|
||||
var programs1 = paths.AsParallel().Where(p => ExecutableApplicationExtensions.Contains(Extension(p))).Select(ExeProgram);
|
||||
var programs2 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(LnkProgram);
|
||||
var programs3 = from p in paths.AsParallel()
|
||||
let e = Extension(p)
|
||||
where e != ShortcutExtension && e != ExeExtension
|
||||
where e != ShortcutExtension && !ExecutableApplicationExtensions.Contains(e)
|
||||
select CreateWin32Program(p);
|
||||
return programs1.Concat(programs2).Concat(programs3);
|
||||
return programs1.Concat(programs2).Where(p => p.Valid).Concat(programs3).Where(p => p.Valid);
|
||||
}
|
||||
|
||||
// Function to obtain the list of applications, the locations of which have been added to the env variable PATH
|
||||
@ -662,14 +707,14 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
var programs1 = allPaths.AsParallel().Where(p => Extension(p).Equals(ShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(LnkProgram);
|
||||
var programs2 = allPaths.AsParallel().Where(p => Extension(p).Equals(ApplicationReferenceExtension, StringComparison.OrdinalIgnoreCase)).Select(CreateWin32Program);
|
||||
var programs3 = allPaths.AsParallel().Where(p => Extension(p).Equals(InternetShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(InternetShortcutProgram);
|
||||
var programs4 = allPaths.AsParallel().Where(p => Extension(p).Equals(ExeExtension, StringComparison.OrdinalIgnoreCase)).Select(ExeProgram);
|
||||
var programs4 = allPaths.AsParallel().Where(p => ExecutableApplicationExtensions.Contains(Extension(p))).Select(ExeProgram);
|
||||
|
||||
var allPrograms = programs1.Concat(programs2).Where(p => p.Valid)
|
||||
.Concat(programs3).Where(p => p.Valid)
|
||||
.Concat(programs4).Where(p => p.Valid)
|
||||
.Select(p =>
|
||||
{
|
||||
p.AppType = (uint)ApplicationTypes.RUN_COMMAND;
|
||||
p.AppType = ApplicationType.RunCommand;
|
||||
return p;
|
||||
});
|
||||
|
||||
@ -696,7 +741,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
var programs1 = paths.AsParallel().Where(p => Extension(p).Equals(ShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(LnkProgram);
|
||||
var programs2 = paths.AsParallel().Where(p => Extension(p).Equals(ApplicationReferenceExtension, StringComparison.OrdinalIgnoreCase)).Select(CreateWin32Program);
|
||||
var programs3 = paths.AsParallel().Where(p => Extension(p).Equals(InternetShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(InternetShortcutProgram);
|
||||
var programs4 = paths.AsParallel().Where(p => Extension(p).Equals(ExeExtension, StringComparison.OrdinalIgnoreCase)).Select(ExeProgram);
|
||||
var programs4 = paths.AsParallel().Where(p => ExecutableApplicationExtensions.Contains(Extension(p))).Select(ExeProgram);
|
||||
|
||||
return programs1.Concat(programs2).Where(p => p.Valid)
|
||||
.Concat(programs3).Where(p => p.Valid)
|
||||
@ -858,7 +903,7 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
// Deduplication code
|
||||
public static Win32Program[] DeduplicatePrograms(ParallelQuery<Win32Program> programs)
|
||||
{
|
||||
var uniqueExePrograms = programs.Where(x => !(string.IsNullOrEmpty(x.LnkResolvedPath) && (Extension(x.FullPath) == ExeExtension) && !(x.AppType == (uint)ApplicationTypes.RUN_COMMAND)));
|
||||
var uniqueExePrograms = programs.Where(x => !(string.IsNullOrEmpty(x.LnkResolvedPath) && ExecutableApplicationExtensions.Contains(Extension(x.FullPath)) && !(x.AppType == ApplicationType.RunCommand)));
|
||||
var uniquePrograms = uniqueExePrograms.Distinct(new RemoveDuplicatesComparer());
|
||||
return uniquePrograms.ToArray();
|
||||
}
|
||||
|
@ -78,6 +78,24 @@ namespace Microsoft.Plugin.Program.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Folder.
|
||||
/// </summary>
|
||||
public static string powertoys_run_plugin_program_folder_type {
|
||||
get {
|
||||
return ResourceManager.GetString("powertoys_run_plugin_program_folder_type", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to File.
|
||||
/// </summary>
|
||||
public static string powertoys_run_plugin_program_generic_file_type {
|
||||
get {
|
||||
return ResourceManager.GetString("powertoys_run_plugin_program_generic_file_type", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Internet shortcut application.
|
||||
/// </summary>
|
||||
|
@ -153,6 +153,12 @@
|
||||
<data name="powertoys_run_plugin_program_file_path" xml:space="preserve">
|
||||
<value>Path</value>
|
||||
</data>
|
||||
<data name="powertoys_run_plugin_program_folder_type" xml:space="preserve">
|
||||
<value>Folder</value>
|
||||
</data>
|
||||
<data name="powertoys_run_plugin_program_generic_file_type" xml:space="preserve">
|
||||
<value>File</value>
|
||||
</data>
|
||||
<data name="powertoys_run_plugin_program_start_failed" xml:space="preserve">
|
||||
<value>Unable to start</value>
|
||||
</data>
|
||||
|
@ -69,6 +69,7 @@ namespace Microsoft.Plugin.Program.Storage
|
||||
string newPath = e.FullPath;
|
||||
|
||||
string extension = Path.GetExtension(newPath);
|
||||
Win32Program.ApplicationType appType = Win32Program.GetAppTypeFromPath(newPath);
|
||||
Programs.Win32Program newApp = Programs.Win32Program.GetAppFromPath(newPath);
|
||||
Programs.Win32Program oldApp = null;
|
||||
|
||||
@ -78,11 +79,11 @@ namespace Microsoft.Plugin.Program.Storage
|
||||
// This situation is not encountered for other application types because the fullPath is the path itself, instead of being computed by using the path to the app.
|
||||
try
|
||||
{
|
||||
if (extension.Equals(LnkExtension, StringComparison.OrdinalIgnoreCase))
|
||||
if (appType == Win32Program.ApplicationType.ShortcutApplication)
|
||||
{
|
||||
oldApp = new Win32Program() { Name = Path.GetFileNameWithoutExtension(e.OldName), ExecutableName = newApp.ExecutableName, FullPath = newApp.FullPath };
|
||||
}
|
||||
else if (extension.Equals(UrlExtension, StringComparison.OrdinalIgnoreCase))
|
||||
else if (appType == Win32Program.ApplicationType.InternetShortcutApplication)
|
||||
{
|
||||
oldApp = new Win32Program() { Name = Path.GetFileNameWithoutExtension(e.OldName), ExecutableName = Path.GetFileName(e.OldName), FullPath = newApp.FullPath };
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Wox.Infrastructure.FileSystemHelper
|
||||
{
|
||||
public class DirectoryWrapper : IDirectoryWrapper
|
||||
{
|
||||
public DirectoryWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Exists(string path)
|
||||
{
|
||||
return System.IO.Directory.Exists(path);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Wox.Infrastructure.FileSystemHelper
|
||||
{
|
||||
public interface IDirectoryWrapper
|
||||
{
|
||||
bool Exists(string path);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user