问题表现

更新 26200.9278 版本后,鼠标指针始终为白色默认指针,重新设置、修改皮肤都无法生效。

修复方法

参考连接:

https://learn.microsoft.com/zh-cn/answers/questions/5983970/windows11-25h2-26220-9223

新建ps1文件并复制粘贴以下代码,右键用powershell运行即可

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
if (-not ('CursorSchemeNative' -as [type])) {
    Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class CursorSchemeNative
{
    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr LoadCursorFromFile(string fileName);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool SetSystemCursor(IntPtr cursor, uint cursorId);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool DestroyCursor(IntPtr cursor);
}
'@
}
$cursorSettings = Get-ItemProperty -LiteralPath 'Registry::HKEY_CURRENT_USER\Control Panel\Cursors'
$cursorMappings = @(
    [pscustomobject]@{ Role = 'Arrow';       CursorId = [uint32]32512 }
    [pscustomobject]@{ Role = 'IBeam';       CursorId = [uint32]32513 }
    [pscustomobject]@{ Role = 'Wait';        CursorId = [uint32]32514 }
    [pscustomobject]@{ Role = 'Crosshair';  CursorId = [uint32]32515 }
    [pscustomobject]@{ Role = 'UpArrow';    CursorId = [uint32]32516 }
    [pscustomobject]@{ Role = 'NWPen';      CursorId = [uint32]32631 }
    [pscustomobject]@{ Role = 'SizeNWSE';   CursorId = [uint32]32642 }
    [pscustomobject]@{ Role = 'SizeNESW';   CursorId = [uint32]32643 }
    [pscustomobject]@{ Role = 'SizeWE';     CursorId = [uint32]32644 }
    [pscustomobject]@{ Role = 'SizeNS';     CursorId = [uint32]32645 }
    [pscustomobject]@{ Role = 'SizeAll';    CursorId = [uint32]32646 }
    [pscustomobject]@{ Role = 'No';         CursorId = [uint32]32648 }
    [pscustomobject]@{ Role = 'Hand';       CursorId = [uint32]32649 }
    [pscustomobject]@{ Role = 'AppStarting';CursorId = [uint32]32650 }
    [pscustomobject]@{ Role = 'Help';       CursorId = [uint32]32651 }
    [pscustomobject]@{ Role = 'Pin';        CursorId = [uint32]32671 }
    [pscustomobject]@{ Role = 'Person';     CursorId = [uint32]32672 }
)
foreach ($mapping in $cursorMappings) {
    Write-Host ''
    Write-Host "========== $($mapping.Role) =========="
    $configuredPath = $cursorSettings.($mapping.Role)
    if ([string]::IsNullOrWhiteSpace([string]$configuredPath)) {
        Write-Host 'Registry path is empty.' -ForegroundColor Yellow
        continue
    }
    $cursorPath = [Environment]::ExpandEnvironmentVariables(
        [string]$configuredPath
    ).Trim('"')
    Write-Host "Path: $cursorPath"
    Write-Host "Cursor ID: $($mapping.CursorId)"
    if (-not (Test-Path -LiteralPath $cursorPath -PathType Leaf)) {
        Write-Host 'FILE NOT FOUND' -ForegroundColor Red
        continue
    }
    Write-Host 'File exists.'
    $cursorHandle = [CursorSchemeNative]::LoadCursorFromFile(
        $cursorPath
    )
    if ($cursorHandle -eq [IntPtr]::Zero) {
        $errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
        Write-Host "LOAD FAILED - Win32 Error: $errorCode" -ForegroundColor Red
        continue
    }
    Write-Host "LoadCursorFromFile: SUCCESS"
    Write-Host "Handle: $cursorHandle"
    $result = [CursorSchemeNative]::SetSystemCursor(
        $cursorHandle,
        $mapping.CursorId
    )
    if ($result) {
        Write-Host "SetSystemCursor: SUCCESS" -ForegroundColor Green
        # IMPORTANT:
        # SetSystemCursor takes ownership of the cursor handle.
        # Do not call DestroyCursor after success.
    }
    else {
        $errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
        Write-Host "SetSystemCursor: FAILED" -ForegroundColor Red
        Write-Host "Win32 Error: $errorCode"
        [void][CursorSchemeNative]::DestroyCursor(
            $cursorHandle
        )
    }
}
Write-Host ''
Write-Host '============================================================'
Write-Host 'Test finished.'
Write-Host 'NO SPI_SETCURSORS WAS CALLED.'
Write-Host '============================================================'

工作原理(AI)

  1. 读取注册表配置
    HKEY_CURRENT_USER\Control Panel\Cursors 中读取每个光标角色(如 ArrowIBeam 等)对应的文件路径。

  2. 加载光标文件
    使用 LoadCursorFromFile API 从路径加载 .cur.ani 光标文件,获得光标句柄。

  3. 替换系统光标
    调用 SetSystemCursor API,将系统预定义光标(通过 CursorId 标识,如 32512 表示 IDC_ARROW)替换为加载的自定义光标。
    SetSystemCursor立即生效,影响当前所有进程(包括桌面和应用程序)。

  4. 错误处理

    • 检查注册表路径是否为空、文件是否存在。

    • 若加载或设置失败,显示 Win32 错误码并清理句柄(DestroyCursor)。

    • 若设置成功,不销毁句柄(系统接管了该句柄的所有权)。

  5. 末尾说明
    脚本特意注明“NO SPI_SETCURSORS WAS CALLED.”,提示它没有通过 SystemParametersInfoSPI_SETCURSORS 来整体刷新光标方案,而是逐项调用 SetSystemCursor 完成替换。