Compare commits

...

2 Commits

Author SHA1 Message Date
Yu Leng (from Dev Box)
0a400c35e7 fix bug 2025-05-09 15:08:03 +08:00
Yu Leng (from Dev Box)
8d2185721e Init 2025-05-09 14:59:30 +08:00
6 changed files with 71 additions and 24 deletions

View File

@@ -1,11 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\..\Common.Dotnet.AotCompatibility.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.Ext.Apps</RootNamespace>
<Nullable>enable</Nullable>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

View File

@@ -1,7 +1,6 @@
GetPhysicallyInstalledSystemMemory
GlobalMemoryStatusEx
GetSystemInfo
CoCreateInstance
SetForegroundWindow
IsIconic
RegisterHotKey
@@ -13,7 +12,6 @@ SetFocus
SetActiveWindow
MonitorFromWindow
GetMonitorInfo
SHCreateStreamOnFileEx
CoAllowSetForegroundWindow
SHCreateStreamOnFileEx
SHLoadIndirectString
SHLoadIndirectString
IStream

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.CmdPal.Ext.Apps.Utils;
using Windows.Win32;
@@ -65,11 +66,18 @@ public partial class UWP
const uint noAttribute = 0x80;
var access = (uint)STGM.READ;
var hResult = PInvoke.SHCreateStreamOnFileEx(path, access, noAttribute, false, null, out IStream stream);
var hResult = Native.SHCreateStreamOnFileEx(path, access, noAttribute, false, IntPtr.Zero, out var streamPtr);
// S_OK
if (hResult == 0)
{
// create IStream from streamPtr
var stream = Marshal.GetTypedObjectForIUnknown(streamPtr, typeof(IStream)) as IStream;
if (stream == null)
{
return;
}
Apps = AppxPackageHelper.GetAppsFromManifest(stream).Select(appInManifest => new UWPApplication(appInManifest, this)).Where(a =>
{
var valid =

View File

@@ -197,9 +197,10 @@ public class UWPApplication : IProgram
parsedFallback = prefix + "///" + key;
}
var outBuffer = new StringBuilder(128);
var outBuffer = new char[1024];
var source = $"@{{{packageFullName}? {parsed}}}";
var capacity = (uint)outBuffer.Capacity;
var capacity = (uint)outBuffer.Length;
var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
if (hResult != HRESULT.S_OK)
{

View File

@@ -5,24 +5,28 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using System.Runtime.InteropServices.Marshalling;
using Dia2Lib;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
[SuppressMessage("Interoperability", "CA1401:P/Invokes should not be visible", Justification = "We want plugins to share this NativeMethods class, instead of each one creating its own.")]
public sealed class Native
public sealed partial class Native
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, nint ppvReserved);
[LibraryImport("shell32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
public static partial int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, nint pbc, ref Guid riid, [MarshalUsing(typeof(IShellItemMarshallerOut))] out IShellItem? shellItem);
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, nint pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
[LibraryImport("shlwapi.dll", StringMarshalling = StringMarshalling.Utf16)]
public static partial HRESULT SHLoadIndirectString(string pszSource, Span<char> pszOutBuf, uint cchOutBuf, nint ppvReserved);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern HRESULT SHCreateStreamOnFileEx(string fileName, STGM grfMode, uint attributes, bool create, System.Runtime.InteropServices.ComTypes.IStream reserved, out System.Runtime.InteropServices.ComTypes.IStream stream);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern HRESULT SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, nint ppvReserved);
[LibraryImport("shlwapi.dll", StringMarshalling = StringMarshalling.Utf16)]
public static partial int SHCreateStreamOnFileEx(
string pszFile,
uint grfMode,
uint dwAttributes,
[MarshalAs(UnmanagedType.Bool)] bool fCreate,
IntPtr pstmTemplate,
out IntPtr ppstm);
public enum HRESULT : uint
{
@@ -129,14 +133,14 @@ public sealed class Native
public interface IShellItem
{
void BindToHandler(
nint pbc,
[MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
out nint ppv);
IntPtr pbc,
ref Guid bhid,
ref Guid riid,
out IntPtr ppv);
void GetParent(out IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
@@ -154,4 +158,24 @@ public sealed class Native
READWRITE = 0x00000002L,
CREATE = 0x00001000L,
}
[CustomMarshaller(typeof(IShellItem), MarshalMode.ManagedToUnmanagedOut, typeof(IShellItemMarshallerOut))]
public static partial class IShellItemMarshallerOut
{
public static IShellItem? ConvertToManaged(IntPtr unmanaged)
{
if (unmanaged == IntPtr.Zero)
{
return null;
}
var obj = Marshal.GetObjectForIUnknown(unmanaged);
return (IShellItem)obj;
}
public static void Free(IntPtr managed)
{
Marshal.FreeCoTaskMem(managed);
}
}
}

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.InteropServices;
using static Microsoft.CmdPal.Ext.Apps.Utils.Native;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
@@ -40,7 +41,20 @@ public class ShellLocalization
return string.Empty;
}
shellItem.GetDisplayName(SIGDN.NORMALDISPLAY, out var filename);
if (shellItem == null)
{
return string.Empty;
}
shellItem.GetDisplayName(SIGDN.NORMALDISPLAY, out var filenamePtr);
// get filename from ptr
var filename = Marshal.PtrToStringUni(filenamePtr);
Marshal.FreeCoTaskMem(filenamePtr);
if (filename == null)
{
return string.Empty;
}
_ = _localizationCache.TryAdd(lowerInvariantPath, filename);