mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
Add exception handling in win32 program (#6958)
* Add exception handling to prevent program from failing due to error in one program * Error handling for program path function * Fix incorrect log value in ProgramLogger
This commit is contained in:
committed by
GitHub
parent
71765238b1
commit
5d095efe90
@@ -330,6 +330,7 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
return ExecutableName;
|
return ExecutableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Any error in CreateWin32Program should not prevent other programs from loading.")]
|
||||||
private static Win32Program CreateWin32Program(string path)
|
private static Win32Program CreateWin32Program(string path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -353,78 +354,94 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
{
|
{
|
||||||
ProgramLogger.Exception($"|Permission denied when trying to load the program from {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
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 };
|
return new Win32Program() { Valid = false, Enabled = false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function filters Internet Shortcut programs
|
// This function filters Internet Shortcut programs
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Any error in InternetShortcutProgram should not prevent other programs from loading.")]
|
||||||
private static Win32Program InternetShortcutProgram(string path)
|
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.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith(iconFilePrefix, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
iconPath = line.Substring(iconFilePrefix.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validApp)
|
|
||||||
{
|
|
||||||
return new Win32Program() { Valid = false, Enabled = false };
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var p = new Win32Program
|
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)
|
||||||
{
|
{
|
||||||
Name = Path.GetFileNameWithoutExtension(path),
|
if (line.StartsWith(urlPrefix, StringComparison.OrdinalIgnoreCase))
|
||||||
ExecutableName = Path.GetFileName(path),
|
{
|
||||||
IcoPath = iconPath,
|
urlPath = line.Substring(urlPrefix.Length);
|
||||||
FullPath = urlPath,
|
|
||||||
UniqueIdentifier = path,
|
try
|
||||||
ParentDirectory = Directory.GetParent(path).FullName,
|
{
|
||||||
Valid = true,
|
Uri uri = new Uri(urlPath);
|
||||||
Enabled = true,
|
}
|
||||||
AppType = ApplicationType.InternetShortcutApplication,
|
catch (UriFormatException e)
|
||||||
};
|
{
|
||||||
return p;
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) when (e is SecurityException || e is UnauthorizedAccessException)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ProgramLogger.Exception($"|Permission denied when trying to load the program from {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
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 };
|
return new Win32Program() { Valid = false, Enabled = false };
|
||||||
}
|
}
|
||||||
@@ -433,9 +450,9 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Unsure of what exceptions are caught here while enabling static analysis")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Unsure of what exceptions are caught here while enabling static analysis")]
|
||||||
private static Win32Program LnkProgram(string path)
|
private static Win32Program LnkProgram(string path)
|
||||||
{
|
{
|
||||||
var program = CreateWin32Program(path);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var program = CreateWin32Program(path);
|
||||||
const int MAX_PATH = 260;
|
const int MAX_PATH = 260;
|
||||||
StringBuilder buffer = new StringBuilder(MAX_PATH);
|
StringBuilder buffer = new StringBuilder(MAX_PATH);
|
||||||
|
|
||||||
@@ -472,13 +489,13 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
// Error caused likely due to trying to get the description of the program
|
// Error caused likely due to trying to get the description of the program
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ProgramLogger.Exception("An unexpected error occurred in the calling method LnkProgram", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
ProgramLogger.Exception($"|An unexpected error occurred in the calling method LnkProgram at {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
||||||
|
|
||||||
program.Valid = false;
|
return new Win32Program() { Valid = false, Enabled = false };
|
||||||
return program;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Any error in ExeProgram should not prevent other programs from loading.")]
|
||||||
private static Win32Program ExeProgram(string path)
|
private static Win32Program ExeProgram(string path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -503,6 +520,12 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
{
|
{
|
||||||
ProgramLogger.Exception($"|Unable to locate exe file at {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
ProgramLogger.Exception($"|Unable to locate exe file at {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 ExeProgram at {path}", e, MethodBase.GetCurrentMethod().DeclaringType, path);
|
||||||
|
|
||||||
return new Win32Program() { Valid = false, Enabled = false };
|
return new Win32Program() { Valid = false, Enabled = false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -585,6 +608,7 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Minimise the effect of error on other programs")]
|
||||||
private static IEnumerable<string> ProgramPaths(string directory, IList<string> suffixes, bool recursiveSearch = true)
|
private static IEnumerable<string> ProgramPaths(string directory, IList<string> suffixes, bool recursiveSearch = true)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
@@ -617,6 +641,10 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
{
|
{
|
||||||
ProgramLogger.Exception($"|Permission denied when trying to load programs from {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
ProgramLogger.Exception($"|Permission denied when trying to load programs from {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ProgramLogger.Exception($"|An unexpected error occurred in the calling method ProgramPaths at {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -635,6 +663,10 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
{
|
{
|
||||||
ProgramLogger.Exception($"|Permission denied when trying to load programs from {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
ProgramLogger.Exception($"|Permission denied when trying to load programs from {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ProgramLogger.Exception($"|An unexpected error occurred in the calling method ProgramPaths at {currentDirectory}", e, MethodBase.GetCurrentMethod().DeclaringType, currentDirectory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (folderQueue.Any());
|
while (folderQueue.Any());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user