Skip to content

Commit be81c4c

Browse files
authored
Fix: Fixed an issue where Run with PowerShell didn't show a window (#15849)
1 parent 868071d commit be81c4c

File tree

10 files changed

+55
-25
lines changed

10 files changed

+55
-25
lines changed

src/Files.App/Actions/Content/Run/RunWithPowershellAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public RunWithPowershellAction()
3131

3232
public Task ExecuteAsync(object? parameter = null)
3333
{
34-
return Win32Helper.RunPowershellCommandAsync($"{context.ShellPage?.SlimContentPage?.SelectedItem?.ItemPath}", false);
34+
return Win32Helper.RunPowershellCommandAsync($"{context.ShellPage?.SlimContentPage?.SelectedItem?.ItemPath}", PowerShellExecutionOptions.None);
3535
}
3636

3737
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)

src/Files.App/Actions/Open/EditInNotepadAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public EditInNotepadAction()
3333

3434
public Task ExecuteAsync(object? parameter = null)
3535
{
36-
return Task.WhenAll(context.SelectedItems.Select(item => Win32Helper.RunPowershellCommandAsync($"notepad '{item.ItemPath}\'", false)));
36+
return Task.WhenAll(context.SelectedItems.Select(item => Win32Helper.RunPowershellCommandAsync($"notepad '{item.ItemPath}\'", PowerShellExecutionOptions.Hidden)));
3737
}
3838

3939
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)

src/Files.App/Actions/Open/OpenInVSCodeAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public OpenInVSCodeAction()
3232

3333
public Task ExecuteAsync(object? parameter = null)
3434
{
35-
return Win32Helper.RunPowershellCommandAsync($"code \'{_context.ShellPage?.ShellViewModel.WorkingDirectory}\'", false);
35+
return Win32Helper.RunPowershellCommandAsync($"code \'{_context.ShellPage?.ShellViewModel.WorkingDirectory}\'", PowerShellExecutionOptions.Hidden);
3636
}
3737

3838
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)

src/Files.App/Actions/Open/OpenRepoInVSCodeAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public OpenRepoInVSCodeAction()
3333

3434
public Task ExecuteAsync(object? parameter = null)
3535
{
36-
return Win32Helper.RunPowershellCommandAsync($"code \'{_context.ShellPage!.InstanceViewModel.GitRepositoryPath}\'", false);
36+
return Win32Helper.RunPowershellCommandAsync($"code \'{_context.ShellPage!.InstanceViewModel.GitRepositoryPath}\'", PowerShellExecutionOptions.Hidden);
3737
}
3838

3939
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Data.Enums
5+
{
6+
/// <summary>
7+
/// Represents options for PowerShell execution.
8+
/// </summary>
9+
[Flags]
10+
public enum PowerShellExecutionOptions
11+
{
12+
/// <summary>
13+
/// Default options.
14+
/// </summary>
15+
None = 0x0,
16+
17+
/// <summary>
18+
/// Run the PowerShell command hidden.
19+
/// </summary>
20+
Hidden = 0x1,
21+
22+
/// <summary>
23+
/// Run PowerShell with elevated privileges.
24+
/// </summary>
25+
Elevated = 0x2
26+
}
27+
}

src/Files.App/Helpers/Win32/Win32Helper.Storage.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,9 @@ public static string ExtractStringFromDLL(string file, int number)
398398
}
399399
}
400400

401-
public static async Task<bool> RunPowershellCommandAsync(string command, bool runAsAdmin)
401+
public static async Task<bool> RunPowershellCommandAsync(string command, PowerShellExecutionOptions options)
402402
{
403-
using Process process = CreatePowershellProcess(command, runAsAdmin);
403+
using Process process = CreatePowershellProcess(command, options);
404404
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(30 * 1000));
405405

406406
try
@@ -425,11 +425,11 @@ public static async Task<bool> RunPowershellCommandAsync(string command, bool ru
425425
}
426426
}
427427

428-
public static bool RunPowershellCommand(string command, bool runAsAdmin)
428+
public static bool RunPowershellCommand(string command, PowerShellExecutionOptions options)
429429
{
430430
try
431431
{
432-
using Process process = CreatePowershellProcess(command, runAsAdmin);
432+
using Process process = CreatePowershellProcess(command, options);
433433

434434
process.Start();
435435

@@ -544,24 +544,24 @@ public static Task OpenFormatDriveDialog(string drive)
544544
{
545545
// Format requires elevation
546546
int driveIndex = drive.ToUpperInvariant()[0] - 'A';
547-
return RunPowershellCommandAsync($"-command \"$Signature = '[DllImport(\\\"shell32.dll\\\", SetLastError = false)]public static extern uint SHFormatDrive(IntPtr hwnd, uint drive, uint fmtID, uint options);'; $SHFormatDrive = Add-Type -MemberDefinition $Signature -Name \"Win32SHFormatDrive\" -Namespace Win32Functions -PassThru; $SHFormatDrive::SHFormatDrive(0, {driveIndex}, 0xFFFF, 0x0001)\"", true);
547+
return RunPowershellCommandAsync($"-command \"$Signature = '[DllImport(\\\"shell32.dll\\\", SetLastError = false)]public static extern uint SHFormatDrive(IntPtr hwnd, uint drive, uint fmtID, uint options);'; $SHFormatDrive = Add-Type -MemberDefinition $Signature -Name \"Win32SHFormatDrive\" -Namespace Win32Functions -PassThru; $SHFormatDrive::SHFormatDrive(0, {driveIndex}, 0xFFFF, 0x0001)\"", PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
548548
}
549549

550550
public static void SetVolumeLabel(string drivePath, string newLabel)
551551
{
552552
// Rename requires elevation
553-
RunPowershellCommand($"-command \"$Signature = '[DllImport(\\\"kernel32.dll\\\", SetLastError = false)]public static extern bool SetVolumeLabel(string lpRootPathName, string lpVolumeName);'; $SetVolumeLabel = Add-Type -MemberDefinition $Signature -Name \"Win32SetVolumeLabel\" -Namespace Win32Functions -PassThru; $SetVolumeLabel::SetVolumeLabel('{drivePath}', '{newLabel}')\"", true);
553+
RunPowershellCommand($"-command \"$Signature = '[DllImport(\\\"kernel32.dll\\\", SetLastError = false)]public static extern bool SetVolumeLabel(string lpRootPathName, string lpVolumeName);'; $SetVolumeLabel = Add-Type -MemberDefinition $Signature -Name \"Win32SetVolumeLabel\" -Namespace Win32Functions -PassThru; $SetVolumeLabel::SetVolumeLabel('{drivePath}', '{newLabel}')\"", PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
554554
}
555555

556556
public static void SetNetworkDriveLabel(string driveName, string newLabel)
557557
{
558-
RunPowershellCommand($"-command \"(New-Object -ComObject Shell.Application).NameSpace('{driveName}').Self.Name='{newLabel}'\"", false);
558+
RunPowershellCommand($"-command \"(New-Object -ComObject Shell.Application).NameSpace('{driveName}').Self.Name='{newLabel}'\"", PowerShellExecutionOptions.Hidden);
559559
}
560560

561561
public static Task<bool> MountVhdDisk(string vhdPath)
562562
{
563563
// Mounting requires elevation
564-
return RunPowershellCommandAsync($"-command \"Mount-DiskImage -ImagePath '{vhdPath}'\"", true);
564+
return RunPowershellCommandAsync($"-command \"Mount-DiskImage -ImagePath '{vhdPath}'\"", PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
565565
}
566566

567567
public static Bitmap? GetBitmapFromHBitmap(HBITMAP hBitmap)
@@ -850,29 +850,32 @@ public static async Task InstallFontsAsync(string[] fontFilePaths, bool forAllUs
850850
if (psCommand.Length + appendCommand.Length > 32766)
851851
{
852852
// The command is too long to run at once, so run the command once up to this point.
853-
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), true);
853+
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
854854
psCommand.Clear().Append("-command \"");
855855
}
856856

857857
psCommand.Append(appendCommand);
858858
}
859859

860-
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), true);
860+
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
861861
}
862862

863-
private static Process CreatePowershellProcess(string command, bool runAsAdmin)
863+
private static Process CreatePowershellProcess(string command, PowerShellExecutionOptions options)
864864
{
865865
Process process = new();
866866

867-
if (runAsAdmin)
867+
process.StartInfo.FileName = "powershell.exe";
868+
if (options.HasFlag(PowerShellExecutionOptions.Elevated))
868869
{
869870
process.StartInfo.UseShellExecute = true;
870871
process.StartInfo.Verb = "runas";
871872
}
872873

873-
process.StartInfo.FileName = "powershell.exe";
874-
process.StartInfo.CreateNoWindow = true;
875-
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
874+
if (options.HasFlag(PowerShellExecutionOptions.Hidden))
875+
{
876+
process.StartInfo.CreateNoWindow = true;
877+
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
878+
}
876879
process.StartInfo.Arguments = command;
877880

878881
return process;

src/Files.App/Services/Storage/StorageSecurityService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public unsafe bool SetOwner(string path, string sid)
5959
{
6060
return Win32Helper.RunPowershellCommand(
6161
$"-command \"try {{ $path = '{path}'; $ID = new-object System.Security.Principal.SecurityIdentifier('{sid}'); $acl = get-acl $path; $acl.SetOwner($ID); set-acl -path $path -aclObject $acl }} catch {{ exit 1; }}\"",
62-
true);
62+
PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
6363
}
6464

6565
return true;

src/Files.App/Services/Windows/WindowsCompatibilityService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ public bool SetCompatibilityOptionsForPath(string filePath, WindowsCompatibility
4141
{
4242
return Win32Helper.RunPowershellCommand(
4343
@$"Remove-ItemProperty -Path 'HKCU:\{_registrySubPath}' -Name '{filePath}' | Out-Null",
44-
true);
44+
PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
4545
}
4646

4747
// Set the new one
4848
return Win32Helper.RunPowershellCommand(
4949
@$"New-ItemProperty -Path 'HKCU:\{_registrySubPath}' -Name '{filePath}' -Value '{options}' -PropertyType String -Force | Out-Null",
50-
true);
50+
PowerShellExecutionOptions.Elevated | PowerShellExecutionOptions.Hidden);
5151
}
5252
}
5353
}

src/Files.App/Utils/Shell/LaunchHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private static async Task<bool> HandleApplicationLaunch(string application, stri
132132
catch (Win32Exception ex) when (ex.NativeErrorCode == 50)
133133
{
134134
// ShellExecute return code 50 (ERROR_NOT_SUPPORTED) for some exes (#15179)
135-
return Win32Helper.RunPowershellCommand($"\"{application}\"", false);
135+
return Win32Helper.RunPowershellCommand($"\"{application}\"", PowerShellExecutionOptions.Hidden);
136136
}
137137
catch (Win32Exception)
138138
{

src/Files.App/ViewModels/Settings/AdvancedViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private async Task SetAsDefaultExplorerAsync()
7878
var dataPath = Environment.ExpandEnvironmentVariables("%LocalAppData%\\Files");
7979
if (IsSetAsDefaultFileManager)
8080
{
81-
if (!await Win32Helper.RunPowershellCommandAsync($"-command \"New-Item -Force -Path '{dataPath}' -ItemType Directory; Copy-Item -Filter *.* -Path '{destFolder}\\*' -Recurse -Force -Destination '{dataPath}'\"", false))
81+
if (!await Win32Helper.RunPowershellCommandAsync($"-command \"New-Item -Force -Path '{dataPath}' -ItemType Directory; Copy-Item -Filter *.* -Path '{destFolder}\\*' -Recurse -Force -Destination '{dataPath}'\"", PowerShellExecutionOptions.Hidden))
8282
{
8383
// Error copying files
8484
await DetectResult();
@@ -87,7 +87,7 @@ private async Task SetAsDefaultExplorerAsync()
8787
}
8888
else
8989
{
90-
await Win32Helper.RunPowershellCommandAsync($"-command \"Remove-Item -Path '{dataPath}' -Recurse -Force\"", false);
90+
await Win32Helper.RunPowershellCommandAsync($"-command \"Remove-Item -Path '{dataPath}' -Recurse -Force\"", PowerShellExecutionOptions.Hidden);
9191
}
9292

9393
try

0 commit comments

Comments
 (0)