mirror of
https://github.com/PowerShell/PowerShell.git
synced 2024-11-23 17:53:58 +08:00
Process reparse points for Microsoft Store applications (#13481)
This commit is contained in:
parent
78d0d0e306
commit
4e2b6e9540
@ -10,7 +10,6 @@ using System.Text;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Xml;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
@ -222,6 +221,29 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets true if Path is Console Application.
|
||||
/// </summary>
|
||||
private bool IsConsoleApplication => !IsWindowsApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Gets true if Path is Windows Application.
|
||||
/// </summary>
|
||||
private bool IsWindowsApplication
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isWindowsApplication.HasValue)
|
||||
{
|
||||
_isWindowsApplication = CheckIfWindowsApplication(Path);
|
||||
}
|
||||
|
||||
return _isWindowsApplication.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _isWindowsApplication;
|
||||
|
||||
#endregion ctor/native command properties
|
||||
|
||||
#region parameter binder
|
||||
@ -476,7 +498,7 @@ namespace System.Management.Automation
|
||||
bool notDone = true;
|
||||
if (!string.IsNullOrEmpty(executable))
|
||||
{
|
||||
if (IsConsoleApplication(executable))
|
||||
if (CheckIfConsoleApplication(executable))
|
||||
{
|
||||
// Allocate a console if there isn't one attached already...
|
||||
ConsoleVisibility.AllocateHiddenConsole();
|
||||
@ -532,7 +554,7 @@ namespace System.Management.Automation
|
||||
_isRunningInBackground = true;
|
||||
if (startInfo.UseShellExecute == false)
|
||||
{
|
||||
_isRunningInBackground = IsWindowsApplication(_nativeProcess.StartInfo.FileName);
|
||||
_isRunningInBackground = IsWindowsApplication;
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,9 +957,9 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsConsoleApplication(string fileName)
|
||||
private static bool CheckIfConsoleApplication(string fileName)
|
||||
{
|
||||
return !IsWindowsApplication(fileName);
|
||||
return !CheckIfWindowsApplication(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -946,10 +968,22 @@ namespace System.Management.Automation
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
[ArchitectureSensitive]
|
||||
private static bool IsWindowsApplication(string fileName)
|
||||
private static bool CheckIfWindowsApplication(string fileName)
|
||||
{
|
||||
#if UNIX
|
||||
return false;
|
||||
#else
|
||||
if (!Platform.IsWindowsDesktop) { return false; }
|
||||
|
||||
// SHGetFileInfo() does not understand reparse points and returns 0 ("non exe or error")
|
||||
// so we are trying to get a real path before.
|
||||
// It is a workaround for Microsoft Store applications.
|
||||
string realPath = Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods.WinInternalGetTarget(fileName);
|
||||
if (realPath is not null)
|
||||
{
|
||||
fileName = realPath;
|
||||
}
|
||||
|
||||
SHFILEINFO shinfo = new SHFILEINFO();
|
||||
IntPtr type = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_EXETYPE);
|
||||
|
||||
@ -968,6 +1002,7 @@ namespace System.Management.Automation
|
||||
// anything else - is a windows program...
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion checkForConsoleApplication
|
||||
@ -1266,7 +1301,7 @@ namespace System.Management.Automation
|
||||
redirectOutput = true;
|
||||
redirectError = true;
|
||||
}
|
||||
else if (Platform.IsWindowsDesktop && IsConsoleApplication(this.Path))
|
||||
else if (Platform.IsWindowsDesktop && IsConsoleApplication)
|
||||
{
|
||||
// On Windows desktops, if the command to run is a console application,
|
||||
// then allocate a console if there isn't one attached already...
|
||||
|
@ -8073,16 +8073,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
if (instance.BaseObject is FileSystemInfo fileSysInfo)
|
||||
{
|
||||
#if !UNIX
|
||||
// We set accessMode parameter to zero because documentation says:
|
||||
// If this parameter is zero, the application can query certain metadata
|
||||
// such as file, directory, or device attributes without accessing
|
||||
// that file or device, even if GENERIC_READ access would have been denied.
|
||||
using (SafeFileHandle handle = OpenReparsePoint(fileSysInfo.FullName, FileDesiredAccess.GenericZero))
|
||||
{
|
||||
string linkTarget = WinInternalGetTarget(handle);
|
||||
|
||||
return linkTarget;
|
||||
}
|
||||
return WinInternalGetTarget(fileSysInfo.FullName);
|
||||
#else
|
||||
return UnixInternalGetTarget(fileSysInfo.FullName);
|
||||
#endif
|
||||
@ -8382,6 +8373,19 @@ namespace Microsoft.PowerShell.Commands
|
||||
return succeeded && (handleInfo.NumberOfLinks > 1);
|
||||
}
|
||||
|
||||
#if !UNIX
|
||||
internal static string WinInternalGetTarget(string path)
|
||||
{
|
||||
// We set accessMode parameter to zero because documentation says:
|
||||
// If this parameter is zero, the application can query certain metadata
|
||||
// such as file, directory, or device attributes without accessing
|
||||
// that file or device, even if GENERIC_READ access would have been denied.
|
||||
using (SafeFileHandle handle = OpenReparsePoint(path, FileDesiredAccess.GenericZero))
|
||||
{
|
||||
return WinInternalGetTarget(handle);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")]
|
||||
private static string WinInternalGetTarget(SafeFileHandle handle)
|
||||
{
|
||||
@ -8456,6 +8460,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
Marshal.FreeHGlobal(outBuffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static bool CreateJunction(string path, string target)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user