Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PT Run] Improve the Win32 Program Indexing speed #11364

Merged
8 changes: 6 additions & 2 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ EXCLUDEFILES
EXCLUDEFOLDERS
EXCLUDESUBFOLDERS
exe
Executables
executionpolicy
exename
exif
Expand Down Expand Up @@ -669,6 +670,7 @@ hardcoded
Hardlines
HARDWAREINPUT
hashcode
Hashset
hbitmap
hbmp
hbr
Expand Down Expand Up @@ -1595,6 +1597,7 @@ REGCLS
regedit
regex
REGISTERCLASSFAILED
Registery
registrypath
regkey
reimplementing
Expand Down Expand Up @@ -1706,6 +1709,7 @@ serizalization
serverside
SETCONTEXT
setcursor
setenv
SETFOCUS
SETFOREGROUND
SETICON
Expand Down Expand Up @@ -1742,8 +1746,8 @@ shlwapi
shobjidl
SHORTCUTATLEAST
shortcutcontrol
shortcutguide
Shortcutguide
shortcutguide
SHORTCUTMAXONEACTIONKEY
SHORTCUTNOREPEATEDMODIFIER
SHORTCUTONEACTIONKEY
Expand Down Expand Up @@ -2160,8 +2164,8 @@ windowsx
windowwalker
winerror
WINEVENT
winexe
winevt
winexe
winforms
winfx
winget
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class Win32Tests
Name = "Microsoft Azure Command Prompt - v2.9",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
Arguments = @"/E:ON /V:ON /K ""C:\Program Files\Microsoft SDKs\Azure\.NET SDK\v2.9\\bin\setenv.cmd""",
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 = Win32Program.ApplicationType.Win32Application,
};
Expand All @@ -59,6 +60,7 @@ public class Win32Tests
Name = "x64 Native Tools Command Prompt for VS 2019",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
Arguments = @"/k ""C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat""",
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 = Win32Program.ApplicationType.Win32Application,
};
Expand Down Expand Up @@ -262,10 +264,10 @@ public void DedupFunctionWhenCalledMustRemoveDuplicateNotepads()
};

// Act
Win32Program[] apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());
List<Win32Program> apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());

// Assert
Assert.AreEqual(1, apps.Length);
Assert.AreEqual(1, apps.Count);
}

[Test]
Expand All @@ -279,10 +281,10 @@ public void DedupFunctionWhenCalledMustRemoveInternetShortcuts()
};

// Act
Win32Program[] apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());
List<Win32Program> apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());

// Assert
Assert.AreEqual(1, apps.Length);
Assert.AreEqual(1, apps.Count);
}

[Test]
Expand All @@ -295,10 +297,10 @@ public void DedupFunctionWhenCalledMustNotRemovelnkWhichdoesNotHaveExe()
};

// Act
Win32Program[] apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());
List<Win32Program> apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());

// Assert
Assert.AreEqual(1, apps.Length);
Assert.AreEqual(1, apps.Count);
}

[Test]
Expand All @@ -312,10 +314,10 @@ public void DedupFunctionMustRemoveDuplicatesForExeExtensionsWithoutLnkResolvedP
};

// Act
Win32Program[] apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());
List<Win32Program> apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());

// Assert
Assert.AreEqual(1, apps.Length);
Assert.AreEqual(1, apps.Count);
Assert.IsTrue(!string.IsNullOrEmpty(apps[0].LnkResolvedPath));
}

Expand All @@ -331,10 +333,10 @@ public void DedupFunctionMustNotRemoveProgramsWithSameExeNameAndFullPath()
};

// Act
Win32Program[] apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());
List<Win32Program> apps = Win32Program.DeduplicatePrograms(prgms.AsParallel());

// Assert
Assert.AreEqual(3, apps.Length);
Assert.AreEqual(3, apps.Count);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public void Win32ProgramRepositoryMustCallOnAppDeletedForUrlAppsWhenDeletedEvent

// 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" });
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;
Expand All @@ -281,7 +281,7 @@ public void Win32ProgramRepositoryMustCallOnAppRenamedForUrlAppsWhenRenamedEvent

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

string oldFullPath = directory + "\\" + oldpath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@ namespace Microsoft.Plugin.Program.Logger
/// </summary>
internal static class ProgramLogger
{
/// <summary>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Warn Method which could be used for non-fatal index related issues (e.g. Not found / not accessible / not parse able)

/// Logs an warning
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
internal static void Warn(string message, Exception ex, Type fullClassName, string loadingProgramPath, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
string calledMethod = "Not available";

if (ex != null)
{
string exceptionCalledMethod = ex.TargetSite != null ? ex.TargetSite.ToString() : ex.StackTrace;
if (!string.IsNullOrEmpty(exceptionCalledMethod))
{
calledMethod = exceptionCalledMethod;
}
}

var msg = $"\n\t\tProgram path: {loadingProgramPath}"
+ $"\n\t\tException thrown in called method: {calledMethod}"
+ $"\n\t\tPossible interpretation of the error: {message}";

// removed looping logic since that is inside Log class
Log.Warn(msg, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}

/// <summary>
/// Logs an exception
/// </summary>
Expand All @@ -29,7 +54,7 @@ internal static void Exception(string message, Exception ex, Type fullClassName,

if (IsKnownWinProgramError(ex, methodName) || IsKnownUWPProgramError(ex, methodName))
{
possibleResolution = "Can be ignored and Wox should still continue, however the program may not be loaded";
possibleResolution = "Can be ignored and PowerToys Run should still continue, however the program may not be loaded";
errorStatus = "KNOWN";
}

Expand Down
28 changes: 14 additions & 14 deletions src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,6 @@ public Main()

// Initialize the Win32ProgramRepository with the settings object
_win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast<IFileSystemWatcherWrapper>().ToList(), new BinaryStorage<IList<Programs.Win32Program>>("Win32"), Settings, _win32ProgramRepositoryHelper.PathsToWatch);

var a = Task.Run(() =>
{
Stopwatch.Normal("Microsoft.Plugin.Program.Main - Win32Program index cost", _win32ProgramRepository.IndexPrograms);
});

var b = Task.Run(() =>
{
Stopwatch.Normal("Microsoft.Plugin.Program.Main - Package index cost", _packageRepository.IndexPrograms);
});

Task.WaitAll(a, b);

Settings.LastIndexTime = DateTime.Today;
}

public void Save()
Expand Down Expand Up @@ -118,6 +104,20 @@ public void Init(PluginInitContext context)
_context.API.ThemeChanged += OnThemeChanged;

UpdateUWPIconPath(_context.API.GetCurrentTheme());

var a = Task.Run(() =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from Constructor to Initialize method so it won't run if you disable the program plugin

{
Stopwatch.Normal("Microsoft.Plugin.Program.Main - Win32Program index cost", _win32ProgramRepository.IndexPrograms);
});

var b = Task.Run(() =>
{
Stopwatch.Normal("Microsoft.Plugin.Program.Main - Package index cost", _packageRepository.IndexPrograms);
});

Task.WaitAll(a, b);

Settings.LastIndexTime = DateTime.Today;
}

public void OnThemeChanged(Theme currentTheme, Theme newTheme)
Expand Down
Loading