Search code examples
windows-10virtual-desktop

Windows 10 IVirtualDesktopManager::MoveWindowToDesktop


I've been trying to use IVirtualDesktopManager::MoveWindowToDesktop to move windows between virtual desktops.

Using it on my own windows works great but unfortunately it fails with E_ACCESSDENIED when I try to use it on the window of another process.

Sadly "Launch as admin" is not good enough for it. Am I missing something that I don't know about COM interfaces or is it just badly designed ?


Solution

  • You can move a window not owned by the executing process, but it requires the use of additional, undocumented COM objects.

    1. Query ImmersiveShell for instances of IApplicationViewCollection and IVirtualDesktopManagerInternal.
    2. Get the hwnd of the window you want to move.
    3. It sounds like you already know the target desktop ID, but you can also use IVirtualDesktopManagerInternal methods GetAdjacentDesktop and GetDesktops to find more.
    4. Call IApplicationViewCollection::GetViewForHwnd to get the view.
    5. Call IVirtualDesktopManagerInternal::MoveViewToDesktop to move the view.

    Code references:

    • VirtualDesktopAccessor wraps the relevant objects in C++ and builds a native DLL you can use.
    • VirtualDesktop wraps them in C# and provides a .NET DLL and GUI.
    • zVirtualDesktop documents different versions of the interfaces.
    • This forum topic shows how to work with the IVirtualDesktopManagerInternal to select a virtual desktop by index in AutoHotKey. I'm working on a version that also wraps IApplicationViewCollection to support moving any given window as described above.