Rob*_*ere 5 powershell winforms
当您在 PowerShell 中创建 Windows 窗体时,即使您更改窗体的图标,它也会与主机控制台窗口分组。
如何将新表单的任务栏图标与 PowerShell 控制台图标分开?
示例代码:
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300,200)
$form.ShowInTaskbar = $true
$form.Icon = New-Object system.drawing.icon 'c:\icon.ico'
$form.Text = 'New taskbar icon plz'
$form.BringToFront()
$form.ShowDialog()
Run Code Online (Sandbox Code Playgroud)
我看到的唯一有点帮助的是一个参考,更改“应用程序 ID”会将其分开,但参考都是 C 代码。
https://msdn.microsoft.com/en-us/magazine/dd942846.aspx
请给出 PowerShell 答案,或者如果答案包含 C# 代码或对其他 API 的调用,请解释它们在 PowerShell 中的工作原理。
在从互联网上通过 C# 魔法拼凑出大量 P/Invoke 后(大部分来自此处,一些来自此处),我最终通过以下方法添加了一种类型,您可以使用以下方法[PSAppID]::SetAppIdForWindow($form.handle, "Your.AppId"):
$signature = @\'\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.ComTypes;\n\npublic class PSAppID\n{\n // https://emoacht.wordpress.com/2012/11/14/csharp-appusermodelid/\n // IPropertyStore Interface\n [ComImport,\n InterfaceType(ComInterfaceType.InterfaceIsIUnknown),\n Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]\n private interface IPropertyStore\n {\n uint GetCount([Out] out uint cProps);\n uint GetAt([In] uint iProp, out PropertyKey pkey);\n uint GetValue([In] ref PropertyKey key, [Out] PropVariant pv);\n uint SetValue([In] ref PropertyKey key, [In] PropVariant pv);\n uint Commit();\n }\n\n\n // PropertyKey Structure\n [StructLayout(LayoutKind.Sequential, Pack = 4)]\n public struct PropertyKey\n {\n private Guid formatId; // Unique GUID for property\n private Int32 propertyId; // Property identifier (PID)\n\n public Guid FormatId\n {\n get\n {\n return formatId;\n }\n }\n\n public Int32 PropertyId\n {\n get\n {\n return propertyId;\n }\n }\n\n public PropertyKey(Guid formatId, Int32 propertyId)\n {\n this.formatId = formatId;\n this.propertyId = propertyId;\n }\n\n public PropertyKey(string formatId, Int32 propertyId)\n {\n this.formatId = new Guid(formatId);\n this.propertyId = propertyId;\n }\n\n }\n\n\n // PropVariant Class (only for string value)\n [StructLayout(LayoutKind.Explicit)]\n public class PropVariant : IDisposable\n {\n [FieldOffset(0)]\n ushort valueType; // Value type\n\n // [FieldOffset(2)]\n // ushort wReserved1; // Reserved field\n // [FieldOffset(4)]\n // ushort wReserved2; // Reserved field\n // [FieldOffset(6)]\n // ushort wReserved3; // Reserved field\n\n [FieldOffset(8)]\n IntPtr ptr; // Value\n\n\n // Value type (System.Runtime.InteropServices.VarEnum)\n public VarEnum VarType\n {\n get { return (VarEnum)valueType; }\n set { valueType = (ushort)value; }\n }\n\n public bool IsNullOrEmpty\n {\n get\n {\n return (valueType == (ushort)VarEnum.VT_EMPTY ||\n valueType == (ushort)VarEnum.VT_NULL);\n }\n }\n\n // Value (only for string value)\n public string Value\n {\n get\n {\n return Marshal.PtrToStringUni(ptr);\n }\n }\n\n\n public PropVariant()\n { }\n\n public PropVariant(string value)\n {\n if (value == null)\n throw new ArgumentException("Failed to set value.");\n\n valueType = (ushort)VarEnum.VT_LPWSTR;\n ptr = Marshal.StringToCoTaskMemUni(value);\n }\n\n ~PropVariant()\n {\n Dispose();\n }\n\n public void Dispose()\n {\n PropVariantClear(this);\n GC.SuppressFinalize(this);\n }\n\n }\n\n [DllImport("Ole32.dll", PreserveSig = false)]\n private extern static void PropVariantClear([In, Out] PropVariant pvar);\n\n\n [DllImport("shell32.dll")]\n private static extern int SHGetPropertyStoreForWindow(\n IntPtr hwnd,\n ref Guid iid /*IID_IPropertyStore*/,\n [Out(), MarshalAs(UnmanagedType.Interface)] out IPropertyStore propertyStore);\n\n public static void SetAppIdForWindow(int handle, string AppId)\n {\n Guid iid = new Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99");\n IPropertyStore prop;\n int result1 = SHGetPropertyStoreForWindow((IntPtr)handle, ref iid, out prop);\n\n // Name = System.AppUserModel.ID\n // ShellPKey = PKEY_AppUserModel_ID\n // FormatID = 9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3\n // PropID = 5\n // Type = String (VT_LPWSTR)\n PropertyKey AppUserModelIDKey = new PropertyKey("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}", 5);\n \n PropVariant pv = new PropVariant(AppId);\n \n uint result2 = prop.SetValue(ref AppUserModelIDKey, pv);\n \n Marshal.ReleaseComObject(prop);\n }\n}\n\'@\n\nAdd-Type -TypeDefinition $signature\nRun Code Online (Sandbox Code Playgroud)\n然后用你的表格:
\n[void][Reflection.Assembly]::LoadWithPartialName(\'Microsoft.VisualBasic\')\nAdd-Type -AssemblyName System.Windows.Forms\nAdd-Type -AssemblyName System.Drawing\n\n$form = New-Object System.Windows.Forms.Form\n$form.Size = New-Object System.Drawing.Size(300,200)\n$form.ShowInTaskbar = $true\n$form.visible = $true\n\n[PSAppID]::SetAppIdForWindow($form.Handle, "YourName.App")\nRun Code Online (Sandbox Code Playgroud)\n它分成自己的任务栏条目。
\nCompanyName.ProductName.SubProduct.VersionInformation其中 Sub\xc2\xadProduct 是可选的,并且仅当您希望应用程序的不同版本被视为不同时才会出现 Version\xc2\xadInformation”。并且不超过 128 个字符。\n\nGuid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")应该是 IPropertyStore 的 Windows Shell ID,但我不知道如何在不写入的情况下获取它。AppUserModelIDKey也许来自某些 Win32 的神奇 GUID也是如此propkey.h?也可以看看:
\n| 归档时间: |
|
| 查看次数: |
1600 次 |
| 最近记录: |