aveyo

RemoveAllVirtualDesktopsRaw

May 18th, 2018 (edited)
1,751
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 26.94 KB | None | 0 0
  1. @(set "0=%~f0"^)#) & powershell -nop -c iex([io.file]::ReadAllText($env:0)) & pause & exit/b
  2.  
  3. $host.ui.rawui.windowtitle = "Delete all virtual desktops"
  4.  
  5. # RemoveAllVirtualDesktopsRaw function by AveYo
  6. # All the heavy lifting done by https://gallery.technet.microsoft.com/scriptcenter/Powershell-commands-to-d0e79cc5
  7.  
  8. # Author: Markus Scholtes, 2017/05/08
  9. # Version 2.10 - support for Windows 11 incl. Insider, 2021/11/27
  10.  
  11. # prefer $PSVersionTable.BuildVersion to [Environment]::OSVersion.Version
  12. # since a wrong Windows version might be returned in RunSpaces
  13. if ($PSVersionTable.PSVersion.Major -lt 6)
  14. { # Powershell 5.x
  15.   $OSVer = $PSVersionTable.BuildVersion.Major
  16.   $OSBuild = $PSVersionTable.BuildVersion.Build
  17. }
  18. else
  19. { # Powershell 6.x or up
  20.   $OSVer = [Environment]::OSVersion.Version.Major
  21.   $OSBuild = [Environment]::OSVersion.Version.Build
  22. }
  23.  
  24. if ($OSVer -lt 10)
  25. {
  26.   Write-Error "Windows 10 or above is required to run this script"
  27.   exit -1
  28. }
  29.  
  30. if ($OSBuild -lt 14393)
  31. {
  32.   Write-Error "Windows 10 1607 or above is required to run this script"
  33.   exit -1
  34. }
  35.  
  36. $Windows1607 = $TRUE
  37. $Windows1803 = $FALSE
  38. $Windows1809 = $FALSE
  39. $Windows11 = $FALSE
  40. $Windows22449 = $FALSE
  41. if ($OSBuild -ge 17134)
  42. {
  43.   $Windows1607 = $FALSE
  44.   $Windows1803 = $TRUE
  45. }
  46. if ($OSBuild -ge 17661)
  47. {
  48.   $Windows1607 = $FALSE
  49.   $Windows1803 = $FALSE
  50.   $Windows1809 = $TRUE
  51. }
  52.  
  53. if ($OSBuild -ge 22000)
  54. {
  55.   $Windows1607 = $FALSE
  56.   $Windows1803 = $FALSE
  57.   $Windows1809 = $FALSE
  58.   $Windows11 = $TRUE
  59. }
  60. if ($OSBuild -ge 22449)
  61. {
  62.   $Windows22449 = $TRUE
  63. }
  64.  
  65. Add-Type -Language CSharp -TypeDefinition @"
  66. using System;
  67. using System.Runtime.InteropServices;
  68. using System.Collections.Generic;
  69. using System.ComponentModel;
  70. using System.Text;
  71.  
  72. // Based on http://stackoverflow.com/a/32417530, Windows 10 SDK, github project Grabacr07/VirtualDesktop and own research
  73.  
  74. namespace VirtualDesktop
  75. {
  76.  
  77.   internal static class Guids
  78.   {
  79.     public static readonly Guid CLSID_ImmersiveShell = new Guid("C2F03A33-21F5-47FA-B4BB-156362A2F239");
  80.     public static readonly Guid CLSID_VirtualDesktopManagerInternal = new Guid("C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B");
  81.     public static readonly Guid CLSID_VirtualDesktopManager = new Guid("AA509086-5CA9-4C25-8F95-589D3C07B48A");
  82.     public static readonly Guid CLSID_VirtualDesktopPinnedApps = new Guid("B5A399E7-1C87-46B8-88E9-FC5747B171BD");
  83.   }
  84.  
  85.   [StructLayout(LayoutKind.Sequential)]
  86.   internal struct Size
  87.   {
  88.     public int X;
  89.     public int Y;
  90.   }
  91.  
  92.   [StructLayout(LayoutKind.Sequential)]
  93.   internal struct Rect
  94.   {
  95.     public int Left;
  96.     public int Top;
  97.     public int Right;
  98.     public int Bottom;
  99.   }
  100.  
  101.   internal enum APPLICATION_VIEW_CLOAK_TYPE : int
  102.   {
  103.     AVCT_NONE = 0,
  104.     AVCT_DEFAULT = 1,
  105.     AVCT_VIRTUAL_DESKTOP = 2
  106.   }
  107.  
  108.   internal enum APPLICATION_VIEW_COMPATIBILITY_POLICY : int
  109.   {
  110.     AVCP_NONE = 0,
  111.     AVCP_SMALL_SCREEN = 1,
  112.     AVCP_TABLET_SMALL_SCREEN = 2,
  113.     AVCP_VERY_SMALL_SCREEN = 3,
  114.     AVCP_HIGH_SCALE_FACTOR = 4
  115.   }
  116.  
  117.   [ComImport]
  118. // https://github.com/mzomparelli/zVirtualDesktop/wiki: Updated interfaces in Windows 10 build 17134, 17661, and 17666
  119. $(if ($Windows1607) {@"
  120. // Windows 10 1607 and Server 2016:
  121.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  122.   [Guid("9AC0B5C8-1484-4C5B-9533-4134A0F97CEA")]
  123. "@ })
  124. $(if ($Windows1803) {@"
  125. // Windows 10 1803:
  126.   [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
  127.   [Guid("871F602A-2B58-42B4-8C4B-6C43D642C06F")]
  128. "@ })
  129. $(if ($Windows1809 -or $Windows11) {@"
  130. // Windows 10 1809 or up and Windows 11:
  131.   [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
  132.   [Guid("372E1D3B-38D3-42E4-A15B-8AB2B178F513")]
  133. "@ })
  134.   internal interface IApplicationView
  135.   {
  136.     int SetFocus();
  137.     int SwitchTo();
  138.     int TryInvokeBack(IntPtr /* IAsyncCallback* */ callback);
  139.     int GetThumbnailWindow(out IntPtr hwnd);
  140.     int GetMonitor(out IntPtr /* IImmersiveMonitor */ immersiveMonitor);
  141.     int GetVisibility(out int visibility);
  142.     int SetCloak(APPLICATION_VIEW_CLOAK_TYPE cloakType, int unknown);
  143.     int GetPosition(ref Guid guid /* GUID for IApplicationViewPosition */, out IntPtr /* IApplicationViewPosition** */ position);
  144.     int SetPosition(ref IntPtr /* IApplicationViewPosition* */ position);
  145.     int InsertAfterWindow(IntPtr hwnd);
  146.     int GetExtendedFramePosition(out Rect rect);
  147.     int GetAppUserModelId([MarshalAs(UnmanagedType.LPWStr)] out string id);
  148.     int SetAppUserModelId(string id);
  149.     int IsEqualByAppUserModelId(string id, out int result);
  150.     int GetViewState(out uint state);
  151.     int SetViewState(uint state);
  152.     int GetNeediness(out int neediness);
  153.     int GetLastActivationTimestamp(out ulong timestamp);
  154.     int SetLastActivationTimestamp(ulong timestamp);
  155.     int GetVirtualDesktopId(out Guid guid);
  156.     int SetVirtualDesktopId(ref Guid guid);
  157.     int GetShowInSwitchers(out int flag);
  158.     int SetShowInSwitchers(int flag);
  159.     int GetScaleFactor(out int factor);
  160.     int CanReceiveInput(out bool canReceiveInput);
  161.     int GetCompatibilityPolicyType(out APPLICATION_VIEW_COMPATIBILITY_POLICY flags);
  162.     int SetCompatibilityPolicyType(APPLICATION_VIEW_COMPATIBILITY_POLICY flags);
  163. $(if ($Windows1607) {@"
  164.     int GetPositionPriority(out IntPtr /* IShellPositionerPriority** */ priority);
  165.     int SetPositionPriority(IntPtr /* IShellPositionerPriority* */ priority);
  166. "@ })
  167.     int GetSizeConstraints(IntPtr /* IImmersiveMonitor* */ monitor, out Size size1, out Size size2);
  168.     int GetSizeConstraintsForDpi(uint uint1, out Size size1, out Size size2);
  169.     int SetSizeConstraintsForDpi(ref uint uint1, ref Size size1, ref Size size2);
  170. $(if ($Windows1607) {@"
  171.     int QuerySizeConstraintsFromApp();
  172. "@ })
  173.     int OnMinSizePreferencesUpdated(IntPtr hwnd);
  174.     int ApplyOperation(IntPtr /* IApplicationViewOperation* */ operation);
  175.     int IsTray(out bool isTray);
  176.     int IsInHighZOrderBand(out bool isInHighZOrderBand);
  177.     int IsSplashScreenPresented(out bool isSplashScreenPresented);
  178.     int Flash();
  179.     int GetRootSwitchableOwner(out IApplicationView rootSwitchableOwner);
  180.     int EnumerateOwnershipTree(out IObjectArray ownershipTree);
  181.     int GetEnterpriseId([MarshalAs(UnmanagedType.LPWStr)] out string enterpriseId);
  182.     int IsMirrored(out bool isMirrored);
  183. $(if ($Windows1803) {@"
  184.     int Unknown1(out int unknown);
  185.     int Unknown2(out int unknown);
  186.     int Unknown3(out int unknown);
  187.     int Unknown4(out int unknown);
  188. "@ })
  189. $(if ($Windows1809 -or $Windows11) {@"
  190.     int Unknown1(out int unknown);
  191.     int Unknown2(out int unknown);
  192.     int Unknown3(out int unknown);
  193.     int Unknown4(out int unknown);
  194.     int Unknown5(out int unknown);
  195.     int Unknown6(int unknown);
  196.     int Unknown7();
  197.     int Unknown8(out int unknown);
  198.     int Unknown9(int unknown);
  199.     int Unknown10(int unknownX, int unknownY);
  200.     int Unknown11(int unknown);
  201.     int Unknown12(out Size size1);
  202. "@ })
  203.   }
  204.  
  205.   [ComImport]
  206.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  207. $(if ($Windows1607) {@"
  208. // Windows 10 1607 and Server 2016:
  209.   [Guid("2C08ADF0-A386-4B35-9250-0FE183476FCC")]
  210. "@ })
  211. $(if ($Windows1803) {@"
  212. // Windows 10 1803:
  213.   [Guid("2C08ADF0-A386-4B35-9250-0FE183476FCC")]
  214. "@ })
  215. $(if ($Windows1809 -or $Windows11) {@"
  216. // Windows 10 1809 or up and Windows 11:
  217.   [Guid("1841C6D7-4F9D-42C0-AF41-8747538F10E5")]
  218. "@ })
  219.   internal interface IApplicationViewCollection
  220.   {
  221.     int GetViews(out IObjectArray array);
  222.     int GetViewsByZOrder(out IObjectArray array);
  223.     int GetViewsByAppUserModelId(string id, out IObjectArray array);
  224.     int GetViewForHwnd(IntPtr hwnd, out IApplicationView view);
  225.     int GetViewForApplication(object application, out IApplicationView view);
  226.     int GetViewForAppUserModelId(string id, out IApplicationView view);
  227.     int GetViewInFocus(out IntPtr view);
  228. $(if ($Windows1803 -or $Windows1809 -or $Windows11) {@"
  229. // Windows 10 1803 or up and Windows 11:
  230.     int Unknown1(out IntPtr view);
  231. "@ })
  232.     void RefreshCollection();
  233.     int RegisterForApplicationViewChanges(object listener, out int cookie);
  234. $(if ($Windows1607) {@"
  235. // Windows 10 1607 and Server 2016:
  236.     int RegisterForApplicationViewPositionChanges(object listener, out int cookie);
  237. "@ })
  238. $(if ($Windows1803) {@"
  239. // Windows 10 1803:
  240.     int RegisterForApplicationViewPositionChanges(object listener, out int cookie);
  241. "@ })
  242.     int UnregisterForApplicationViewChanges(int cookie);
  243.   }
  244.  
  245.   [ComImport]
  246.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  247. $(if ($Windows11) {@"
  248. // Windows 11:
  249.   [Guid("536D3495-B208-4CC9-AE26-DE8111275BF8")]
  250. "@ } else {@"
  251. // Windows 10:
  252.   [Guid("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4")]
  253. "@ })
  254.   internal interface IVirtualDesktop
  255.   {
  256.     bool IsViewVisible(IApplicationView view);
  257.     Guid GetId();
  258. $(if ($Windows11) {@"
  259.     IntPtr Unknown1();
  260.     [return: MarshalAs(UnmanagedType.HString)]
  261.     string GetName();
  262.     [return: MarshalAs(UnmanagedType.HString)]
  263.     string GetWallpaperPath();
  264. "@ })
  265.   }
  266.  
  267.   [ComImport]
  268.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  269. $(if ($Windows11) {@"
  270. // Windows 11:
  271.   [Guid("B2F925B9-5A0F-4D2E-9F4D-2B1507593C10")]
  272.   internal interface IVirtualDesktopManagerInternal
  273.   {
  274.     int GetCount(IntPtr hWndOrMon);
  275.     void MoveViewToDesktop(IApplicationView view, IVirtualDesktop desktop);
  276.     bool CanViewMoveDesktops(IApplicationView view);
  277.     IVirtualDesktop GetCurrentDesktop(IntPtr hWndOrMon);
  278. "@ })
  279. $(if ($Windows22449) {@"
  280. // Windows 11 Insider:
  281.     IObjectArray GetAllCurrentDesktops();
  282. "@ })
  283. $(if ($Windows11) {@"
  284.     void GetDesktops(IntPtr hWndOrMon, out IObjectArray desktops);
  285.     [PreserveSig]
  286.     int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
  287.     void SwitchDesktop(IntPtr hWndOrMon, IVirtualDesktop desktop);
  288.     IVirtualDesktop CreateDesktop(IntPtr hWndOrMon);
  289.     void MoveDesktop(IVirtualDesktop desktop, IntPtr hWndOrMon, int nIndex);
  290.     void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
  291.     IVirtualDesktop FindDesktop(ref Guid desktopid);
  292.     void GetDesktopSwitchIncludeExcludeViews(IVirtualDesktop desktop, out IObjectArray unknown1, out IObjectArray unknown2);
  293.     void SetDesktopName(IVirtualDesktop desktop, [MarshalAs(UnmanagedType.HString)] string name);
  294.     void SetDesktopWallpaper(IVirtualDesktop desktop, [MarshalAs(UnmanagedType.HString)] string path);
  295.     void UpdateWallpaperPathForAllDesktops([MarshalAs(UnmanagedType.HString)] string path);
  296.     void CopyDesktopState(IApplicationView pView0, IApplicationView pView1);
  297.     int GetDesktopIsPerMonitor();
  298.     void SetDesktopIsPerMonitor(bool state);
  299.   }
  300.  
  301. "@ } else {@"
  302. // Windows 10:
  303.   [Guid("F31574D6-B682-4CDC-BD56-1827860ABEC6")]
  304.   internal interface IVirtualDesktopManagerInternal
  305.   {
  306.     int GetCount();
  307.     void MoveViewToDesktop(IApplicationView view, IVirtualDesktop desktop);
  308.     bool CanViewMoveDesktops(IApplicationView view);
  309.     IVirtualDesktop GetCurrentDesktop();
  310.     void GetDesktops(out IObjectArray desktops);
  311.     [PreserveSig]
  312.     int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
  313.     void SwitchDesktop(IVirtualDesktop desktop);
  314.     IVirtualDesktop CreateDesktop();
  315.     void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
  316.     IVirtualDesktop FindDesktop(ref Guid desktopid);
  317.   }
  318.  
  319.   [ComImport]
  320.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  321.   [Guid("0F3A72B0-4566-487E-9A33-4ED302F6D6CE")]
  322.   internal interface IVirtualDesktopManagerInternal2
  323.   {
  324.     int GetCount();
  325.     void MoveViewToDesktop(IApplicationView view, IVirtualDesktop desktop);
  326.     bool CanViewMoveDesktops(IApplicationView view);
  327.     IVirtualDesktop GetCurrentDesktop();
  328.     void GetDesktops(out IObjectArray desktops);
  329.     [PreserveSig]
  330.     int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
  331.     void SwitchDesktop(IVirtualDesktop desktop);
  332.     IVirtualDesktop CreateDesktop();
  333.     void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
  334.     IVirtualDesktop FindDesktop(ref Guid desktopid);
  335.     void Unknown1(IVirtualDesktop desktop, out IntPtr unknown1, out IntPtr unknown2);
  336.     void SetName(IVirtualDesktop desktop, [MarshalAs(UnmanagedType.HString)] string name);
  337.   }
  338. "@ })
  339.  
  340.   [ComImport]
  341.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  342.   [Guid("A5CD92FF-29BE-454C-8D04-D82879FB3F1B")]
  343.   internal interface IVirtualDesktopManager
  344.   {
  345.     bool IsWindowOnCurrentVirtualDesktop(IntPtr topLevelWindow);
  346.     Guid GetWindowDesktopId(IntPtr topLevelWindow);
  347.     void MoveWindowToDesktop(IntPtr topLevelWindow, ref Guid desktopId);
  348.   }
  349.  
  350.   [ComImport]
  351.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  352.   [Guid("4CE81583-1E4C-4632-A621-07A53543148F")]
  353.   internal interface IVirtualDesktopPinnedApps
  354.   {
  355.     bool IsAppIdPinned(string appId);
  356.     void PinAppID(string appId);
  357.     void UnpinAppID(string appId);
  358.     bool IsViewPinned(IApplicationView applicationView);
  359.     void PinView(IApplicationView applicationView);
  360.     void UnpinView(IApplicationView applicationView);
  361.   }
  362.  
  363.   [ComImport]
  364.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  365.   [Guid("92CA9DCD-5622-4BBA-A805-5E9F541BD8C9")]
  366.   internal interface IObjectArray
  367.   {
  368.     void GetCount(out int count);
  369.     void GetAt(int index, ref Guid iid, [MarshalAs(UnmanagedType.Interface)]out object obj);
  370.   }
  371.  
  372.   [ComImport]
  373.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  374.   [Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
  375.   internal interface IServiceProvider10
  376.   {
  377.     [return: MarshalAs(UnmanagedType.IUnknown)]
  378.     object QueryService(ref Guid service, ref Guid riid);
  379.   }
  380.  
  381.  
  382.  
  383.   internal static class DesktopManager
  384.   {
  385.     static DesktopManager()
  386.     {
  387.       var shell = (IServiceProvider10)Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_ImmersiveShell));
  388.       VirtualDesktopManagerInternal = (IVirtualDesktopManagerInternal)shell.QueryService(Guids.CLSID_VirtualDesktopManagerInternal, typeof(IVirtualDesktopManagerInternal).GUID);
  389. $(if (-not $Windows11) {@"
  390. // Windows 10:
  391.       try {
  392.         VirtualDesktopManagerInternal2 = (IVirtualDesktopManagerInternal2)shell.QueryService(Guids.CLSID_VirtualDesktopManagerInternal, typeof(IVirtualDesktopManagerInternal2).GUID);
  393.       }
  394.       catch {
  395.         VirtualDesktopManagerInternal2 = null;
  396.       }
  397. "@ })
  398.       VirtualDesktopManager = (IVirtualDesktopManager)Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_VirtualDesktopManager));
  399.       ApplicationViewCollection = (IApplicationViewCollection)shell.QueryService(typeof(IApplicationViewCollection).GUID, typeof(IApplicationViewCollection).GUID);
  400.       VirtualDesktopPinnedApps = (IVirtualDesktopPinnedApps)shell.QueryService(Guids.CLSID_VirtualDesktopPinnedApps, typeof(IVirtualDesktopPinnedApps).GUID);
  401.     }
  402.  
  403.     internal static IVirtualDesktopManagerInternal VirtualDesktopManagerInternal;
  404. $(if (-not $Windows11) {@"
  405. // Windows 10:
  406.     internal static IVirtualDesktopManagerInternal2 VirtualDesktopManagerInternal2;
  407. "@ })
  408.     internal static IVirtualDesktopManager VirtualDesktopManager;
  409.     internal static IApplicationViewCollection ApplicationViewCollection;
  410.     internal static IVirtualDesktopPinnedApps VirtualDesktopPinnedApps;
  411.  
  412.     internal static IVirtualDesktop GetDesktop(int index)
  413.     { // get desktop with index
  414. $(if (-not $Windows11) {@"
  415.       int count = VirtualDesktopManagerInternal.GetCount();
  416. "@ } else {@"
  417.       int count = VirtualDesktopManagerInternal.GetCount(IntPtr.Zero);
  418. "@ })
  419.       if (index < 0 || index >= count) throw new ArgumentOutOfRangeException("index");
  420.       IObjectArray desktops;
  421. $(if (-not $Windows11) {@"
  422.       VirtualDesktopManagerInternal.GetDesktops(out desktops);
  423. "@ } else {@"
  424.       VirtualDesktopManagerInternal.GetDesktops(IntPtr.Zero, out desktops);
  425. "@ })
  426.       object objdesktop;
  427.       desktops.GetAt(index, typeof(IVirtualDesktop).GUID, out objdesktop);
  428.       Marshal.ReleaseComObject(desktops);
  429.       return (IVirtualDesktop)objdesktop;
  430.     }
  431.  
  432.     internal static int GetDesktopIndex(IVirtualDesktop desktop)
  433.     { // get index of desktop
  434.       int index = -1;
  435.       Guid IdSearch = desktop.GetId();
  436.       IObjectArray desktops;
  437. $(if (-not $Windows11) {@"
  438.       VirtualDesktopManagerInternal.GetDesktops(out desktops);
  439. "@ } else {@"
  440.       VirtualDesktopManagerInternal.GetDesktops(IntPtr.Zero, out desktops);
  441. "@ })
  442.       object objdesktop;
  443. $(if (-not $Windows11) {@"
  444.       for (int i = 0; i < VirtualDesktopManagerInternal.GetCount(); i++)
  445. "@ } else {@"
  446.       for (int i = 0; i < VirtualDesktopManagerInternal.GetCount(IntPtr.Zero); i++)
  447. "@ })
  448.       {
  449.         desktops.GetAt(i, typeof(IVirtualDesktop).GUID, out objdesktop);
  450.         if (IdSearch.CompareTo(((IVirtualDesktop)objdesktop).GetId()) == 0)
  451.         { index = i;
  452.           break;
  453.         }
  454.       }
  455.       Marshal.ReleaseComObject(desktops);
  456.       return index;
  457.     }
  458.  
  459.     internal static IApplicationView GetApplicationView(this IntPtr hWnd)
  460.     { // get application view to window handle
  461.       IApplicationView view;
  462.       ApplicationViewCollection.GetViewForHwnd(hWnd, out view);
  463.       return view;
  464.     }
  465.  
  466.     internal static string GetAppId(IntPtr hWnd)
  467.     { // get Application ID to window handle
  468.       string appId;
  469.       hWnd.GetApplicationView().GetAppUserModelId(out appId);
  470.       return appId;
  471.     }
  472.   }
  473.  
  474.  
  475.  
  476.   public class Desktop
  477.   {
  478.     // Get window handle of current console window (even if powershell started in cmd)
  479.     [DllImport("Kernel32.dll")]
  480.     public static extern IntPtr GetConsoleWindow();
  481.  
  482.         // get process id to window handle
  483.         [DllImport("user32.dll")]
  484.         private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
  485.  
  486.         // get handle of active window
  487.         [DllImport("user32.dll")]
  488.         public static extern IntPtr GetForegroundWindow();
  489.  
  490.     private IVirtualDesktop ivd;
  491.     private Desktop(IVirtualDesktop desktop) { this.ivd = desktop; }
  492.  
  493.     public override int GetHashCode()
  494.     { // Get hash
  495.       return ivd.GetHashCode();
  496.     }
  497.  
  498.     public override bool Equals(object obj)
  499.     { // Compares with object
  500.       var desk = obj as Desktop;
  501.       return desk != null && object.ReferenceEquals(this.ivd, desk.ivd);
  502.     }
  503.  
  504.     public static int Count
  505.     { // return the number of desktops
  506. $(if (-not $Windows11) {@"
  507.       get { return DesktopManager.VirtualDesktopManagerInternal.GetCount(); }
  508. "@ } else {@"
  509.       get { return DesktopManager.VirtualDesktopManagerInternal.GetCount(IntPtr.Zero); }
  510. "@ })
  511.     }
  512.  
  513.     public static Desktop Current
  514.     { // returns current desktop
  515. $(if (-not $Windows11) {@"
  516.       get { return new Desktop(DesktopManager.VirtualDesktopManagerInternal.GetCurrentDesktop()); }
  517. "@ } else {@"
  518.       get { return new Desktop(DesktopManager.VirtualDesktopManagerInternal.GetCurrentDesktop(IntPtr.Zero)); }
  519. "@ })
  520.     }
  521.  
  522.     public static Desktop FromIndex(int index)
  523.     { // return desktop object from index (-> index = 0..Count-1)
  524.       return new Desktop(DesktopManager.GetDesktop(index));
  525.     }
  526.  
  527.     public static Desktop FromWindow(IntPtr hWnd)
  528.     { // return desktop object to desktop on which window <hWnd> is displayed
  529.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  530.       Guid id = DesktopManager.VirtualDesktopManager.GetWindowDesktopId(hWnd);
  531.       return new Desktop(DesktopManager.VirtualDesktopManagerInternal.FindDesktop(ref id));
  532.     }
  533.  
  534.     public static int FromDesktop(Desktop desktop)
  535.     { // return index of desktop object or -1 if not found
  536.       return DesktopManager.GetDesktopIndex(desktop.ivd);
  537.     }
  538.  
  539.     public static Desktop Create()
  540.     { // create a new desktop
  541. $(if (-not $Windows11) {@"
  542.       return new Desktop(DesktopManager.VirtualDesktopManagerInternal.CreateDesktop());
  543. "@ } else {@"
  544.       return new Desktop(DesktopManager.VirtualDesktopManagerInternal.CreateDesktop(IntPtr.Zero));
  545. "@ })
  546.     }
  547.  
  548.     public void Remove(Desktop fallback = null)
  549.     { // destroy desktop and switch to <fallback>
  550.       IVirtualDesktop fallbackdesktop;
  551.       if (fallback == null)
  552.       { // if no fallback is given use desktop to the left except for desktop 0.
  553.         Desktop dtToCheck = new Desktop(DesktopManager.GetDesktop(0));
  554.         if (this.Equals(dtToCheck))
  555.         { // desktop 0: set fallback to second desktop (= "right" desktop)
  556.           DesktopManager.VirtualDesktopManagerInternal.GetAdjacentDesktop(ivd, 4, out fallbackdesktop); // 4 = RightDirection
  557.         }
  558.         else
  559.         { // set fallback to "left" desktop
  560.           DesktopManager.VirtualDesktopManagerInternal.GetAdjacentDesktop(ivd, 3, out fallbackdesktop); // 3 = LeftDirection
  561.         }
  562.       }
  563.       else
  564.         // set fallback desktop
  565.         fallbackdesktop = fallback.ivd;
  566.  
  567.       DesktopManager.VirtualDesktopManagerInternal.RemoveDesktop(ivd, fallbackdesktop);
  568.     }
  569.  
  570.     public bool IsVisible
  571.     { // return true if this desktop is the current displayed one
  572. $(if (-not $Windows11) {@"
  573.       get { return object.ReferenceEquals(ivd, DesktopManager.VirtualDesktopManagerInternal.GetCurrentDesktop()); }
  574. "@ } else {@"
  575.       get { return object.ReferenceEquals(ivd, DesktopManager.VirtualDesktopManagerInternal.GetCurrentDesktop(IntPtr.Zero)); }
  576. "@ })
  577.     }
  578.  
  579.     public void MakeVisible()
  580.     { // make this desktop visible
  581. $(if (-not $Windows11) {@"
  582.       DesktopManager.VirtualDesktopManagerInternal.SwitchDesktop(ivd);
  583. "@ } else {@"
  584.       DesktopManager.VirtualDesktopManagerInternal.SwitchDesktop(IntPtr.Zero, ivd);
  585. "@ })
  586.     }
  587.  
  588.     public Desktop Left
  589.     { // return desktop at the left of this one, null if none
  590.       get
  591.       {
  592.         IVirtualDesktop desktop;
  593.         int hr = DesktopManager.VirtualDesktopManagerInternal.GetAdjacentDesktop(ivd, 3, out desktop); // 3 = LeftDirection
  594.         if (hr == 0)
  595.           return new Desktop(desktop);
  596.         else
  597.           return null;
  598.       }
  599.     }
  600.  
  601.     public Desktop Right
  602.     { // return desktop at the right of this one, null if none
  603.       get
  604.       {
  605.         IVirtualDesktop desktop;
  606.         int hr = DesktopManager.VirtualDesktopManagerInternal.GetAdjacentDesktop(ivd, 4, out desktop); // 4 = RightDirection
  607.         if (hr == 0)
  608.           return new Desktop(desktop);
  609.         else
  610.           return null;
  611.       }
  612.     }
  613.  
  614.     public void MoveWindow(IntPtr hWnd)
  615.     { // move window to this desktop
  616.       int processId;
  617.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  618.       GetWindowThreadProcessId(hWnd, out processId);
  619.  
  620.       if (hWnd == GetConsoleWindow())
  621.       { // own window
  622.         try // the easy way (powershell's own console)
  623.         {
  624.           DesktopManager.VirtualDesktopManager.MoveWindowToDesktop(hWnd, ivd.GetId());
  625.         }
  626.         catch // powershell in cmd console
  627.         {
  628.           IApplicationView view;
  629.           DesktopManager.ApplicationViewCollection.GetViewForHwnd(hWnd, out view);
  630.           DesktopManager.VirtualDesktopManagerInternal.MoveViewToDesktop(view, ivd);
  631.         }
  632.       }
  633.       else
  634.       { // window of other process
  635.         IApplicationView view;
  636.         DesktopManager.ApplicationViewCollection.GetViewForHwnd(hWnd, out view);
  637.         try {
  638.           DesktopManager.VirtualDesktopManagerInternal.MoveViewToDesktop(view, ivd);
  639.         }
  640.         catch
  641.         { // could not move active window, try main window (or whatever windows thinks is the main window)
  642.           DesktopManager.ApplicationViewCollection.GetViewForHwnd(System.Diagnostics.Process.GetProcessById(processId).MainWindowHandle, out view);
  643.         DesktopManager.VirtualDesktopManagerInternal.MoveViewToDesktop(view, ivd);
  644.       }
  645.     }
  646.     }
  647.    
  648.     public void MoveActiveWindow()
  649.     { // move active window to this desktop
  650.       MoveWindow(GetForegroundWindow());
  651.     }
  652.  
  653.     public bool HasWindow(IntPtr hWnd)
  654.     { // return true if window is on this desktop
  655.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  656.       return ivd.GetId() == DesktopManager.VirtualDesktopManager.GetWindowDesktopId(hWnd);
  657.     }
  658.  
  659.     public static bool IsWindowPinned(IntPtr hWnd)
  660.     { // return true if window is pinned to all desktops
  661.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  662.       return DesktopManager.VirtualDesktopPinnedApps.IsViewPinned(hWnd.GetApplicationView());
  663.     }
  664.  
  665.     public static void PinWindow(IntPtr hWnd)
  666.     { // pin window to all desktops
  667.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  668.       var view = hWnd.GetApplicationView();
  669.       if (!DesktopManager.VirtualDesktopPinnedApps.IsViewPinned(view))
  670.       { // pin only if not already pinned
  671.         DesktopManager.VirtualDesktopPinnedApps.PinView(view);
  672.       }
  673.     }
  674.  
  675.     public static void UnpinWindow(IntPtr hWnd)
  676.     { // unpin window from all desktops
  677.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  678.       var view = hWnd.GetApplicationView();
  679.       if (DesktopManager.VirtualDesktopPinnedApps.IsViewPinned(view))
  680.       { // unpin only if not already unpinned
  681.         DesktopManager.VirtualDesktopPinnedApps.UnpinView(view);
  682.       }
  683.     }
  684.  
  685.     public static bool IsApplicationPinned(IntPtr hWnd)
  686.     { // return true if application for window is pinned to all desktops
  687.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  688.       return DesktopManager.VirtualDesktopPinnedApps.IsAppIdPinned(DesktopManager.GetAppId(hWnd));
  689.     }
  690.  
  691.     public static void PinApplication(IntPtr hWnd)
  692.     { // pin application for window to all desktops
  693.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  694.       string appId = DesktopManager.GetAppId(hWnd);
  695.       if (!DesktopManager.VirtualDesktopPinnedApps.IsAppIdPinned(appId))
  696.       { // pin only if not already pinned
  697.         DesktopManager.VirtualDesktopPinnedApps.PinAppID(appId);
  698.       }
  699.     }
  700.  
  701.     public static void UnpinApplication(IntPtr hWnd)
  702.     { // unpin application for window from all desktops
  703.       if (hWnd == IntPtr.Zero) throw new ArgumentNullException();
  704.       var view = hWnd.GetApplicationView();
  705.       string appId = DesktopManager.GetAppId(hWnd);
  706.       if (DesktopManager.VirtualDesktopPinnedApps.IsAppIdPinned(appId))
  707.       { // unpin only if pinned
  708.         DesktopManager.VirtualDesktopPinnedApps.UnpinAppID(appId);
  709.       }
  710.     }
  711.   }
  712.  
  713. }
  714. "@
  715.  
  716. Function RemoveAllVirtualDesktopsRaw
  717. {
  718.   $VDCount=([VirtualDesktop.Desktop]::Count)-1;
  719.   write-host number of virtual desktops: 0 - $VDCount;
  720.  
  721.   $VDCurrent=([VirtualDesktop.Desktop]::Current);
  722.   $VDIndex=[VirtualDesktop.Desktop]::FromDesktop(([VirtualDesktop.Desktop]::Current));
  723.   write-host current virtual desktop: $VDIndex;
  724.  
  725.   $ErrorActionPreference='SilentlyContinue';
  726.   For ($i=$VDCount; $i -ge 0; $i--) {
  727. #   if ($i -eq $VDIndex) {
  728. #     write-host - skipping $i... [current];
  729. #     continue;
  730. #   }
  731. #   write-host - removing $i...;
  732.     $VDTarget = [VirtualDesktop.Desktop]::FromIndex($i);
  733. #   if ($VDTarget -is [VirtualDesktop.Desktop])
  734. #   {
  735.       $VDTarget.Remove($VDCurrent);
  736. #   }
  737.   }
  738. }
  739.  
  740. $started=(GET-DATE);
  741. RemoveAllVirtualDesktopsRaw
  742. $finished=(NEW-TIMESPAN $started);
  743. write-host "done in $($finished.Seconds).$($finished.MilliSeconds) seconds"
  744.  
Add Comment
Please, Sign In to add comment