本篇博文我仅仅是作为记录者,实际上发现并编码的是我们组的小伙伴天保同学。
我们组小伙伴有个需求,需要将WPF应用的 任务栏右键菜单菜单,不显示**"固定到任务栏"**。
如下图:
普通窗口的任务栏右键菜单:


但是发现部分窗口有只显示 "关闭窗口"
如**"微信公众号"**的窗口

微软的官方文档:System.AppUserModel.PreventPinning - Win32 apps | Microsoft Learn 禁用将快捷方式或窗口固定到任务栏或 开始 菜单的功能。 此属性还使项无法包含在 "开始" 菜单的"最常用的"(MFU)列表中。
1、首先定义System.AppUserModel.PreventPinning:ROPERTYKEY(new Guid("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 9):详情看propertyKey的参数解释:propertyKEY (wtypes.h) - Win32 apps | Microsoft Learn
2、给IPropertyStore 定义 IID Guid IID_IPropertyStore = new Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99");
3、调用shell32 的 SHGetPropertyStoreForWindow实现 禁用的功能
代码如下:
public class NativeWin32
{
[DllImport("shell32.dll")]
public static extern int SHGetPropertyStoreForWindow(IntPtr hwnd, ref Guid riid, out IPropertyStore propertyStore);
[DllImport("ole32.dll")]
public static extern int PropVariantClear(ref PROPVARIANT pvar);
// Define IPropertyStore interface
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
public interface IPropertyStore
{
void GetCount(out uint cProps);
void GetAt(uint iProp, out PROPERTYKEY pkey);
void GetValue(ref PROPERTYKEY key, out PROPVARIANT pv);
void SetValue(ref PROPERTYKEY key, ref PROPVARIANT pv);
void Commit();
}
// Define IID for IPropertyStore
public static Guid IID_IPropertyStore = new Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99");
// Define PROPERTYKEY struct
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct PROPERTYKEY
{
public Guid fmtid;
public uint pid;
public PROPERTYKEY(Guid fmtid, uint pid)
{
this.fmtid = fmtid;
this.pid = pid;
}
}
// Define PROPVARIANT structure (simplified, we'll use a simple one for bool)
[StructLayout(LayoutKind.Explicit)]
public struct PROPVARIANT
{
// We'll only implement the necessary part for boolean
[FieldOffset(0)] public ushort vt;
[FieldOffset(8)] public byte boolVal;
public void SetValue(bool value)
{
// VT_BOOL
vt = 11;
boolVal = value ? (byte)1 : (byte)0;
}
}
}
在窗口加载的时候调用方法:
public MainWindow()
{
InitializeComponent();
SourceInitialized += MainWindow_SourceInitialized;
}
private void MainWindow_SourceInitialized(object? sender, EventArgs e)
{
SetPinning();
}
private void SetPinning()
{
IntPtr hwnd = new WindowInteropHelper(this).Handle;
// Define the property key for System.AppUserModel.PreventPinning
NativeWin32.PROPERTYKEY propKey = new NativeWin32.PROPERTYKEY(new Guid("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 9);
// Get the IPropertyStore for the window
NativeWin32.IPropertyStore propStore;
int hr = NativeWin32.SHGetPropertyStoreForWindow(hwnd, ref NativeWin32.IID_IPropertyStore, out propStore);
if (hr != 0) // if failed
{
Marshal.ThrowExceptionForHR(hr);
}
try
{
// Create a PROPVARIANT with bool value: true
NativeWin32.PROPVARIANT pv = new NativeWin32.PROPVARIANT();
pv.SetValue(true);
// Set the property
propStore.SetValue(ref propKey, ref pv);
// We must free the PROPVARIANT
NativeWin32.PropVariantClear(ref pv);
}
finally
{
// Release the IPropertyStore
Marshal.ReleaseComObject(propStore);
}
}
结果如下:

参考资料:
propertyKEY (wtypes.h) - Win32 apps | Microsoft Learn
System.AppUserModel.PreventPinning - Win32 apps | Microsoft Learn
应用程序用户模型 ID (AppUserModelIDs) - Win32 apps | Microsoft Learn