title: How to implement Windows 10 IVirtualDesktopManager interface in Python?
body: <p>I'm trying to implement <a href="https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager" rel="nofollow noreferrer">IVirtualDesktopManager interface</a> (and <a href="https://stackoverflow.com/a/55542867/11703358">hopefully</a> IVirtualDesktopManagerInternal afterward) in Python based on <a href="https://stackoverflow.com/questions/40196874/how-to-use-the-ivirtualdesktopmanager-interface-in-c-win32/40197171#40197171">this SO answer</a>, but I'm stuck.</p>
  
  <hr>
  
  <p>Edit: I want a working example in Python that will at least lead me to the implementation of IsWindowOnCurrentVirtualDesktop method - it should return a Boolean when a hwnd is passed to it.</p>
  
  <hr>
  
  <p>Using pywin32 I'm able to get to some point in the process, but I'm not sure neither if I even can do that in pure Python nor how to continue:</p>
  
  <pre><code># bypythoncom.py
  import pythoncom
  import pywintypes
  
  """IServiceProvider* pServiceProvider = NULL;
  HRESULT hr = ::CoCreateInstance(
      CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER,
      __uuidof(IServiceProvider), (PVOID*)&amp;pServiceProvider);"""
  
  CLSID_ImmersiveShell = pywintypes.IID("{C2F03A33-21F5-47FA-B4BB-156362A2F239}")
  
  provider = pythoncom.CoCreateInstance(
      CLSID_ImmersiveShell,
      None,
      pythoncom.CLSCTX_LOCAL_SERVER,
      pythoncom.IID_IServiceProvider,
  )
  print(provider)
  
  """if (SUCCEEDED(hr))
  {
      IVirtualDesktopManager *pDesktopManager = NULL;
      hr = pServiceProvider-&gt;QueryService(__uuidof(IVirtualDesktopManager), &amp;pDesktopManager);
  
      if (SUCCEEDED(hr))
      {
          BOOL bIsOnCurrentDesktop = FALSE;
          hr = pDesktopManager-&gt;IsWindowOnCurrentVirtualDesktop(hWnd, &amp;bIsOnCurrentDesktop);
  
          if (SUCCEEDED(hr))
          {
              // use bIsOnCurrentDesktop as needed...
          }
  
          pDesktopManager-&gt;Release();
      }
  
      pServiceProvider-&gt;Release();
  }
  """
  
  manager = provider.QueryService(
      pywintypes.IID("{a5cd92ff-29be-454c-8d04-d82879fb3f1b}"),
      pythoncom.IID_IUnknown,
  )
  print(manager)
  
  # C:\dev\examples\desktops&gt;python bypythoncom.py
  # &lt;PyIServiceProvider at 0x002A7170 with obj at 0x001C256C&gt;
  # &lt;PyIUnknown at 0x002A7188 with obj at 0x002AB2F4&gt;
  </code></pre>
  
  <p>Using comtypes I don't know what to use as <code>interface</code> argument to QueryService:</p>
  
  <pre><code># bycomtypes.py
  import comtypes
  import comtypes.client
  from comtypes.GUID import GUID
  
  clsid = GUID("{C2F03A33-21F5-47FA-B4BB-156362A2F239}")  # CLSID_ImmersiveShell
  
  service_provider = comtypes.client.CreateObject(clsid, interface=comtypes.IServiceProvider)
  print(service_provider)
  
  iid = GUID("{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}") # IID_IVirtualDesktopManager
  
  manager = service_provider.QueryService(
      iid, interface
  )
  
  # C:\dev\examples\desktops&gt;python bycomtypes.py
  # &lt;POINTER(IServiceProvider) ptr=0xbd8d04 at 30c8e90&gt;
  </code></pre>
  
  <p>I'm not really sure what I should do after getting provider, <code>IUnknown</code> has only <code>QueryInterface</code> method exposed, here's another ctypes and comtypes try:</p>
  
  <pre><code>import ctypes
  from comtypes import IUnknown, CLSCTX_LOCAL_SERVER
  from comtypes.GUID import GUID
  
  ole32 = ctypes.windll.ole32
  # ole32.CoInitialize(None)
  
  CLSID_ImmersiveShell = GUID("{C2F03A33-21F5-47FA-B4BB-156362A2F239}")
  IID_IServiceProvider = GUID("{6D5140C1-7436-11CE-8034-00AA006009FA}")
  
  provider = ctypes.POINTER(IUnknown)()
  ole32.CoCreateInstance(
      ctypes.byref(CLSID_ImmersiveShell),
      None,
      CLSCTX_LOCAL_SERVER,
      ctypes.byref(IID_IServiceProvider),
      ctypes.byref(provider),
  )
  print(provider)
  
  IID_IVirtualDesktopManager = GUID("{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
  instance = provider.QueryInterface(IUnknown, IID_IVirtualDesktopManager)
  
  # C:\dev\examples\desktops&gt;python byctypes.py
  # &lt;POINTER(IUnknown) ptr=0x8b294 at 8a26c0&gt;
  # Traceback (most recent call last):
  #   File "another.py", line 22, in &lt;module&gt;
  #     instance = provider.QueryInterface(IUnknown, IID_IVirtualDesktopManager)
  #   File "C:\dev\venvs\project\lib\site-packages\comtypes\__init__.py", line 1158, in QueryInterface
  #     self.__com_QueryInterface(byref(iid), byref(p))
  # _ctypes.COMError: (-2147467262, 'No such interface supported', (None, None, None, 0, None))
  </code></pre>
  
  <hr>
  
  <p>Edit2: I changed the last example so it reveals what @Baget points at. An excerpt from the <a href="https://github.com/enthought/comtypes/blob/master/comtypes/__init__.py" rel="nofollow noreferrer">actual implementation</a> in Python of comtypes.IUnknown's QueryInterface is:</p>
  
  <pre><code>def QueryInterface(self, interface, iid=None):
      "QueryInterface(interface) -&gt; instance"
      p = POINTER(interface)()
      if iid is None:
          iid = interface._iid_
  </code></pre>
  
  <hr>
  
  <p>I would be grateful if someone gives a hint on how to do this or links some implementation I may follow to do the job.</p>