关于桌面句柄的windowsAPI使用问题

win11,在获取桌面句柄后使用ListView_GetItem(hwndDesktop, &lvItem);函数获取桌面文件信息时会导致桌面窗口崩溃,句柄刷新,搞不懂是为啥

源码如下:

#include <Windows.h>
#include <CommCtrl.h>
#include <ShellApi.h>
#include <ShObjIdl.h>

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    // 将窗口最小化
    ShowWindow(hwnd, SW_MINIMIZE);

    // 继续枚举
    return TRUE;
}

//要移动特定桌面图标,可以使用Windows API函数来实现。
//以下是一个示例代码,假设我们要移动"我的电脑"图标。
int main() {
    // 获取“我的电脑”图标的句柄
    
    HWND hwndWorkerW = NULL;
    HWND hwndProgman = NULL;
    HWND hShellDefView = NULL;
    HWND hwndDesktop = NULL;
    HWND copyhwnd = NULL;
    while (hwndDesktop == NULL)//必须存在桌面窗口层次
    {
        hwndWorkerW = ::FindWindowEx(0, hwndWorkerW, L"WorkerW", NULL);//获得WorkerW类的窗口
        if (hwndWorkerW == NULL)
            break;//未知错误
        hShellDefView = ::FindWindowEx(hwndWorkerW, NULL, L"SHELLDLL_DefView", NULL);
        if (hShellDefView == NULL)
            continue;
        hwndDesktop = ::FindWindowEx(hShellDefView, NULL, L"SysListView32", NULL);
    }
    if (hwndDesktop == 0)
    {
        while (hwndDesktop == NULL)
        {
            copyhwnd = hwndDesktop;
            hwndProgman = FindWindow(L"Progman", L"Program Manager");

            SendMessageTimeout(hwndProgman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);

            hShellDefView = FindWindowEx(hwndProgman, NULL, L"SHELLDLL_DefView", NULL);
            SendMessageTimeout(hShellDefView, 0x100, 0, 0, SMTO_NORMAL, 1000, nullptr);

            hwndDesktop = FindWindowEx(hShellDefView, NULL, L"SysListView32", L"FolderView");
            if (copyhwnd == hwndDesktop)
            {
                break;
            }
        }
        while (hwndDesktop == NULL)//必须存在桌面窗口层次
        {
            hwndWorkerW = ::FindWindowEx(0, hwndWorkerW, L"WorkerW", NULL);//获得WorkerW类的窗口
            if (hwndWorkerW == NULL)
                break;//未知错误
            hShellDefView = ::FindWindowEx(hwndWorkerW, NULL, L"SHELLDLL_DefView", NULL);
            if (hShellDefView == NULL)
                continue;
            hwndDesktop = ::FindWindowEx(hShellDefView, NULL, L"SysListView32", NULL);
        }
    }

    HICON hIcon = NULL;
    int nCount = ListView_GetItemCount(hwndDesktop);
    
    //此句的作用是显示桌面
    //ShellExecute(NULL, L"open", L"Shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257}", NULL, NULL, SW_SHOWNORMAL);
    // 构造 LVITEM 结构体

    LVITEM lvItem = { 0 };
    lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;


    for (int i = 0; i < nCount; i++)
    {
        lvItem.iItem = i;

        // 获取指定项的图标信息和状态
        ListView_GetItem(hwndDesktop, &lvItem);

        // 如果是需要的索引
        if (i == 50)
        {
            // 计算要移动到的位置
            int nX = 1000;// 新的 x 坐标
            int nY = 1000;// 新的 y 坐标

            // 发送 LVM_SETITEMPOSITION 消息移动图标
            ListView_SetItemPosition(hwndDesktop, i, nX, nY);

            // 更新桌面
            SendMessage(hwndWorkerW, WM_COMMAND, 0x7402, 0);

            break;
        }
    }



    //HWND item = FindWindowEx(hwndDesktop, nullptr, L"SysListView32", L"FolderView");
    //int x = 100, y = 100;

    // 移动图标
    //LPARAM pos = MAKELPARAM(x, y); // 在x,y位置上放置图标
    //SendMessage(hIcon, LVM_SETITEMPOSITION, 0, pos);


    return 0;
}
//该代码中,我们首先获取桌面窗口的句柄,然后通过句柄查找到桌面窗口中的ListView控件,
//这个控件用于显示桌面图标。然后我们再通过句柄查找到特定的图标,
//并使用LVM_SETITEMPOSITION消息来将其移动到指定位置(x,y)。