Love your Virtual Desktop! When I upgraded to Windows 11 25H2 the SetDesktopName stopped working for me. While I won't pretend to understand everything happening, with the help of Gemini I've ended up with the following code, which I can confirm creates a virtual desktop, and sets the name appropriately in Windows 11 25H2. Posting here if it helps you with a 25H2 revision.
// Original Author: Markus Scholtes, 2025
// Version 1.21, 2025-08-11
// Modified Version for Windows 11 25H2
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Diagnostics;
namespace VirtualDesktop
{
#region COM API
internal static class Guids
{
public static readonly Guid CLSID_ImmersiveShell = new Guid("C2F03A33-21F5-47FA-B4BB-156362A2F239");
public static readonly Guid CLSID_VirtualDesktopManagerInternal = new Guid("C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B");
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("92CA9DCD-5622-4BBA-A805-5E9F541BD8C9")]
internal interface IObjectArray
{
void GetCount(out int count);
void GetAt(int index, ref Guid iid, [MarshalAs(UnmanagedType.Interface)] out object obj);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("3F07F4BE-B107-441A-AF0F-39D82529072C")]
internal interface IVirtualDesktop
{
void Unused1();
Guid GetId();
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("53F5CA0B-158F-4124-900C-057158060B27")]
internal interface IVirtualDesktopManagerInternal
{
int GetCount();
void MoveViewToDesktop(object view, IVirtualDesktop desktop);
bool CanViewMoveDesktops(object view);
IVirtualDesktop GetCurrentDesktop();
void GetDesktops(out IObjectArray desktops);
[PreserveSig] int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
void SwitchDesktop(IVirtualDesktop desktop);
void SwitchDesktopAndMoveForegroundView(IVirtualDesktop desktop);
IVirtualDesktop CreateDesktop();
void MoveDesktop(IVirtualDesktop desktop, int nIndex);
void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
IVirtualDesktop FindDesktop(ref Guid desktopid);
void GetDesktopSwitchIncludeExcludeViews(IVirtualDesktop desktop, out IObjectArray unknown1, out IObjectArray unknown2);
// FIX: Use IntPtr instead of string to avoid Marshaling error
void SetDesktopName(IVirtualDesktop desktop, IntPtr hstringName);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
internal interface IServiceProvider10
{
[return: MarshalAs(UnmanagedType.IUnknown)] object QueryService(ref Guid service, ref Guid riid);
}
#endregion
internal static class DesktopManager
{
static DesktopManager()
{
var shell = (IServiceProvider10)Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_ImmersiveShell));
VirtualDesktopManagerInternal = (IVirtualDesktopManagerInternal)shell.QueryService(Guids.CLSID_VirtualDesktopManagerInternal, typeof(IVirtualDesktopManagerInternal).GUID);
}
internal static IVirtualDesktopManagerInternal VirtualDesktopManagerInternal;
}
public class Desktop
{
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString, uint length, out IntPtr hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int WindowsDeleteString(IntPtr hstring);
private IVirtualDesktop ivd;
private Desktop(IVirtualDesktop desktop) { this.ivd = desktop; }
public static Desktop Create() => new Desktop(DesktopManager.VirtualDesktopManagerInternal.CreateDesktop());
public void SetName(string Name)
{
IntPtr hString = IntPtr.Zero;
try
{
// 1. Manually create the WinRT HString
WindowsCreateString(Name, (uint)Name.Length, out hString);
// 2. Pass the raw pointer to the COM method
DesktopManager.VirtualDesktopManagerInternal.SetDesktopName(this.ivd, hString);
}
catch (Exception ex)
{
Debug.WriteLine("SetName COM failed: " + ex.Message);
}
finally
{
if (hString != IntPtr.Zero) WindowsDeleteString(hString);
}
public void MakeVisible()
{
DesktopManager.VirtualDesktopManagerInternal.SwitchDesktop(this.ivd);
}
}
}
Love your Virtual Desktop! When I upgraded to Windows 11 25H2 the SetDesktopName stopped working for me. While I won't pretend to understand everything happening, with the help of Gemini I've ended up with the following code, which I can confirm creates a virtual desktop, and sets the name appropriately in Windows 11 25H2. Posting here if it helps you with a 25H2 revision.