Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b82d0c3
Fix: Update PotPlayer Website link
memstechtips Jan 27, 2026
2fd6ff5
feat: Add Hungarian translation. Credit to @JohnFowler58 for translation
memstechtips Jan 27, 2026
e780e6a
Update Gitignore
memstechtips Jan 27, 2026
3d19eaa
refactor: Remove redundant OneDrive registry check in AppStatusDiscov…
memstechtips Jan 27, 2026
2f2700e
fix: Portable apps creating shortcuts to wrong executable
memstechtips Jan 28, 2026
7c7b4cd
fix: Fixed an issue where OneDriveRemoval unintentionally caused star…
memstechtips Jan 30, 2026
984c41c
feat: Migrate WinGet from CLI to COM API for improved reliability
memstechtips Jan 30, 2026
0b9a22c
chore: Update license from CC BY-NC-SA 4.0 to MIT
memstechtips Jan 30, 2026
449adfd
chore: Update license from CC BY-NC-SA 4.0 to MIT
memstechtips Jan 30, 2026
49b8a68
First launch after migration
memstechtips Jan 31, 2026
452f271
SettingsPage Finalized
memstechtips Feb 1, 2026
185ebf9
Fix logging & refactor to DataTemplateSelector + ContentControl
memstechtips Feb 1, 2026
7e95e95
Create SettingTemplates & Update Pages
memstechtips Feb 2, 2026
1cad18d
Title Bar Done
memstechtips Feb 2, 2026
8940b5b
Navigation Sidebar Done
memstechtips Feb 2, 2026
bec905f
MoreMenu Flyout Done
memstechtips Feb 2, 2026
48c015f
SettingDefinition Icons Done.
memstechtips Feb 2, 2026
e5b3f97
Add FeatureIcons and Finish Nav Button Icons
memstechtips Feb 2, 2026
ff828cc
CustomizePage Header 50% done
memstechtips Feb 2, 2026
b126a95
CustomizePage Done
memstechtips Feb 2, 2026
ac79ffa
MainWindow, NavBar, MoreMenu & CustomizePage Localization Done
memstechtips Feb 3, 2026
1d7bdd2
Finalize CustomizePage Overview Descriptions & Sub Feature GroupNames
memstechtips Feb 3, 2026
6a5e9e9
Finalize Customize & Sub Features Layout Incl. Badges on SettingsCards
memstechtips Feb 4, 2026
a0e75ee
CustomizePage Search Fixed
memstechtips Feb 4, 2026
02546b4
CustomizePage Localization Done
memstechtips Feb 4, 2026
9729950
Finalize CustomizePage with Content Background
memstechtips Feb 4, 2026
032f515
PowerPlan ComboBox Done
memstechtips Feb 5, 2026
1a4e076
ParentSettingId & AdvancedUnlock Done
memstechtips Feb 5, 2026
37ef084
Remove Badges & Implement InfoBars. Update ComboBox dropdown behaviours
memstechtips Feb 5, 2026
06f974d
SoftwareApps Header & Tabs Done
memstechtips Feb 5, 2026
ff59e57
SoftwareApps DataGrid Styling Fixed
memstechtips Feb 6, 2026
81272ff
Add SoftwareApps View Modes & AutounattendGeneratorPage
memstechtips Feb 6, 2026
4dd8da2
Fix ScrollViewer Padding in WindowsAppsHelpContent
memstechtips Feb 6, 2026
167f57d
Add TaskProgressControl, WindowSize and Position Persistence, Add Upd…
memstechtips Feb 6, 2026
05c8ef3
feat: add Arabic localization
qais-mle7y Feb 7, 2026
48ba81e
Remove duplicate language entry for German
qais-mle7y Feb 7, 2026
0999c0f
Merge pull request #405 from qais-mle7y/feat/add-arabic-localization
memstechtips Feb 8, 2026
ac346c7
Add Arabic Translation @qais-mle7y
memstechtips Feb 9, 2026
c8e4aee
Add Config Import Review Process
memstechtips Feb 9, 2026
bc49147
Clean Up Translations and Fix Missing Usage of Localization Keys
memstechtips Feb 9, 2026
9a646ad
Remove WPF project, fix search bug, and clean up unused converters
memstechtips Feb 9, 2026
8357469
Merge remote-tracking branch 'origin/dev-ui' into dev
memstechtips Feb 9, 2026
4dc441a
Remove CommandService & PowerShellExecutionService & Replace with Nat…
memstechtips Feb 10, 2026
23cb77d
Finalize v26.02.13
memstechtips Feb 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: Portable apps creating shortcuts to wrong executable
Modified ExternalAppsService to create Start Menu folders containing shortcuts to all executables instead of guessing the main executable. Users can now access all .exe files for portable/zip packages.

Fixes #321
  • Loading branch information
memstechtips committed Jan 28, 2026
commit 2f2700e02b9a292fa9fd7e76c35fd3778790de0a
Original file line number Diff line number Diff line change
Expand Up @@ -90,57 +90,43 @@ private async Task CreateStartMenuShortcutForPortableAppAsync(ItemDefinition ite
{
try
{
var exePath = FindPortableAppExecutable(item);
if (string.IsNullOrEmpty(exePath))
var installDir = FindPortableAppDirectory(item);
if (string.IsNullOrEmpty(installDir))
{
logService.LogWarning($"Could not find executable for portable app {item.Name}");
logService.LogWarning($"Could not find installation directory for {item.Name}");
return;
}

var startMenuPath = Path.Combine(
var exeFiles = Directory.GetFiles(installDir, "*.exe", SearchOption.AllDirectories).ToList();
if (!exeFiles.Any())
{
logService.LogWarning($"No executables found for {item.Name}");
return;
}

var startMenuFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Programs),
$"{item.Name}.lnk");
item.Name);

var script = $@"
$WshShell = New-Object -ComObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut('{startMenuPath.Replace("'", "''")}')
$Shortcut.TargetPath = '{exePath.Replace("'", "''")}'
$Shortcut.WorkingDirectory = '{Path.GetDirectoryName(exePath)?.Replace("'", "''")}'
$Shortcut.Description = '{item.Name.Replace("'", "''")}'
$Shortcut.Save()
";
Directory.CreateDirectory(startMenuFolder);

var startInfo = new ProcessStartInfo
foreach (var exePath in exeFiles)
{
FileName = "powershell",
Arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{script.Replace("\"", "\\\"")}\"",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
var exeName = Path.GetFileNameWithoutExtension(exePath);
var shortcutPath = Path.Combine(startMenuFolder, $"{exeName}.lnk");

using var process = new Process { StartInfo = startInfo };
process.Start();
await process.WaitForExitAsync();

if (process.ExitCode == 0)
{
logService.LogInformation($"Created Start Menu shortcut for portable app: {item.Name} -> {exePath}");
}
else
{
var error = await process.StandardError.ReadToEndAsync();
logService.LogWarning($"Failed to create shortcut for {item.Name}: {error}");
await CreateShortcutAsync(shortcutPath, exePath, Path.GetDirectoryName(exePath), item.Name);
}

logService.LogInformation($"Created Start Menu folder with {exeFiles.Count} shortcuts for {item.Name}");
}
catch (Exception ex)
{
logService.LogWarning($"Error creating Start Menu shortcut for {item.Name}: {ex.Message}");
logService.LogWarning($"Error creating Start Menu shortcuts for {item.Name}: {ex.Message}");
}
}

private string? FindPortableAppExecutable(ItemDefinition item)
private string? FindPortableAppDirectory(ItemDefinition item)
{
var searchPaths = new[]
{
Expand All @@ -155,30 +141,48 @@ private async Task CreateStartMenuShortcutForPortableAppAsync(ItemDefinition ite
if (!Directory.Exists(basePath))
continue;

var matchingDirs = item.WinGetPackageId!
var matchingDir = item.WinGetPackageId!
.SelectMany(pkgId => Directory.GetDirectories(basePath, $"{pkgId}*"))
.Distinct()
.ToList();
.FirstOrDefault();

foreach (var dir in matchingDirs)
{
var exeFiles = Directory.GetFiles(dir, "*.exe", SearchOption.AllDirectories)
.Where(f => !Path.GetFileName(f).StartsWith("unins", StringComparison.OrdinalIgnoreCase))
.ToList();
if (matchingDir != null)
return matchingDir;
}

if (!exeFiles.Any())
continue;
return null;
}

// Try to find an exe that matches the app name
var appNamePart = item.Name.Split(' ')[0];
var bestMatch = exeFiles.FirstOrDefault(e =>
Path.GetFileNameWithoutExtension(e).Contains(appNamePart, StringComparison.OrdinalIgnoreCase));
private async Task CreateShortcutAsync(string shortcutPath, string targetPath, string workingDir, string description)
{
var script = $@"
$WshShell = New-Object -ComObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut('{shortcutPath.Replace("'", "''")}')
$Shortcut.TargetPath = '{targetPath.Replace("'", "''")}'
$Shortcut.WorkingDirectory = '{workingDir?.Replace("'", "''")}'
$Shortcut.Description = '{description.Replace("'", "''")}'
$Shortcut.Save()
";

return bestMatch ?? exeFiles.First();
}
}
var startInfo = new ProcessStartInfo
{
FileName = "powershell",
Arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{script.Replace("\"", "\\\"")}\"",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};

return null;
using var process = new Process { StartInfo = startInfo };
process.Start();
await process.WaitForExitAsync();

if (process.ExitCode != 0)
{
var error = await process.StandardError.ReadToEndAsync();
logService.LogWarning($"Failed to create shortcut at {shortcutPath}: {error}");
}
}

public async Task<OperationResult<bool>> UninstallAppAsync(ItemDefinition item, IProgress<TaskProgressDetail>? progress = null)
Expand Down Expand Up @@ -210,19 +214,19 @@ private void RemoveStartMenuShortcutIfExists(string appName)
{
try
{
var shortcutPath = Path.Combine(
var startMenuFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Programs),
$"{appName}.lnk");
appName);

if (File.Exists(shortcutPath))
if (Directory.Exists(startMenuFolder))
{
File.Delete(shortcutPath);
logService.LogInformation($"Removed Start Menu shortcut for {appName}");
Directory.Delete(startMenuFolder, true);
logService.LogInformation($"Removed Start Menu folder for {appName}");
}
}
catch (Exception ex)
{
logService.LogWarning($"Could not remove Start Menu shortcut for {appName}: {ex.Message}");
logService.LogWarning($"Could not remove Start Menu folder for {appName}: {ex.Message}");
}
}

Expand Down