代码之家  ›  专栏  ›  技术社区  ›  DontPanic

桌面快捷方式的位置存储在哪里?

  •  0
  • DontPanic  · 技术社区  · 6 年前

    Windows桌面快捷方式的位置存储在哪里?

    我在问屏幕的事 位置 不是真正的图标本身。我知道图标本身存储在各种DLL、EXE等中。位置清楚地存储在一些非易失性存储中,因为它们通过重新引导持续存在。


    我知道这是可能的,因为许多可用的应用程序都会这样做(例如,“WinTidy”)。

    http://williballethin.com.forensics/shellbags ,但那只是 不是捷径。这些都在注册处的各个地方,包括

    `HKEY_CURRENT_USER/Software/Microsoft/Windows/Shell/Bags/1/Desktop`  
    `HKEY_USERS/.DEFAULT/Software/Microsoft/Windows/Shell/Bags/1/Desktop`  
    

    我编写了一个程序来提取这些值,但是键值的格式无法理解。

    有人知道它们是怎么存放在哪里的吗?

    0 回复  |  直到 6 年前
        1
  •  0
  •   DontPanic    6 年前


    ++++++++++++++++++++++++++++++++++++++
    我刚切换到Win10 64位计算机,发现下面的解决方案不再有效。我相信是因为桌面内部的改变。我知道怎么做。请参阅本答案末尾的“WIN10附录”。
    ++++++++++++++++++++++++++++++++++++++

    我终于想出了如何做我想要的(显示和重新排列桌面图标)。我最初的问题是定位、读取和写入存储图标信息的文件,但这是 一种有用的方法。以下是我学到的:

    帮助,因为退出时它将被覆盖。

    操作桌面项的正确方法是直接操作ListView中的项。任何更改在更改时立即可见,并在退出时保存。为了访问这些项目,我们可以使用几个Windows消息:LVM_GETITEM、LVM_GETITEMCOUNT、LVM_GETITEMPOSITION和LVM_SETITEMPOSITION。这些消息使用起来相当简单,但有一个复杂性:有些消息需要指向参数结构的指针。这些结构必须 地址空间

    • 在应用程序中声明一个点结构。

    • 在中分配镜像结构 资源管理器的地址空间 使用API VirtualAllocEx()。

    • 使用API ReadProcessMemory()将结果读回应用程序点。此函数可以跨不同的地址空间读取内存。

    我已经将这些操作原型化,它们按我的要求工作。我的代码很长,但我会尽快发布摘录。

    更新日期:10/4/2019------------------------------------

    创建了一组常用的实用程序函数,使代码更简洁易读。它们被命名为“exp*()”并包含在末尾。参考资料可在 http://ramrodtechnology.com/explorer . 这里的许多基本技术都被无耻地偷走了 https://www.codeproject.com/Articles/5570/Stealing-Program-s-Memory

    安装程序

    // COMMONLY USED VARS
    HANDLE hProcess;        // explorer process handle
    HWND hWndLV;        // explorer main window
    
    // SET UP CONVENIENCE VARS
    hProcess = expGetProcessHandle();   // get explorer process handle
    if( !hProcess ) exit( 1 );
    hWndLV = expGetListView();      // get main ListView of Desktop
    if( !hWndLV   ) exit( 1 );
    

    函数打印所有项目名称

    //@ Process a list view window and print item names
    int
    printAllNames()
    {
        int ok,icount,indx;
        LVITEM item;                    // point in app space
        LVITEM *_pitem;                 // point in exp space
        char text[512];
        char *_ptext;
        int nr,nwrite;              // count of bytes read/written
        
        printf( "\n" );
    
        // ALLOC ITEMS IN EXP SPACE
        _pitem = expAlloc( sizeof(LVITEM) );
        _ptext = expAlloc( sizeof(text  ) );
    
    
        printf( "  NAME\n" );
        printf( "  ==================================\n" );
        icount = expGetItemCount();
        for( indx=0; indx<icount; indx++ ) {            // for each item in LV
    
          // SETUP ITEM IN EXP SPACE
          memset( &item, 0, sizeof(LVITEM) );   // preclear
          item.iItem      = indx;       // index of item to read
          item.iSubItem   = 0;          // sub index (always 0)
          item.mask       = LVIF_TEXT;      // component to read
          item.pszText    = _ptext;     // buffer to recv text
          item.cchTextMax = sizeof(text);   // size of buffer
    
          // WRITE ITEM REQ TO EXP SPACE
          ok = WriteProcessMemory( hProcess, _pitem, &item, sizeof(LVITEM), &nwrite );
    
          // SEND MESSAGE TO GET ITEM INTO EXP SPACE
          ok = SendMessage( hWndLV, LVM_GETITEM, indx, (LPARAM)_pitem );
    
          // READ EXP TEXT INTO APP SPACE
          memset( &item, 0, sizeof(LVITEM) );
          ok = ReadProcessMemory( hProcess, _pitem, &item, sizeof(POINT), &nr );
          ok = ReadProcessMemory( hProcess, _ptext, &text, sizeof(text),  &nr );
    
          // PRINT RESULT
          printf( "  %s\n", text );
        }
        ok = expFree( _pitem );
        ok = expFree( _ptext );
    
        return( TRUE );
        //r Returns TRUE on success, FALSE on error
    }  
    

    函数打印所有项目位置

    //@ Process a list view window and print position
    int
    printAllPositions()
    {
        int ok,icount,indx,nr;
        POINT pt;                   // point in app space
        POINT *_ppt;                    // point in exp space
        
        icount = expGetItemCount();
    
        _ppt = expAlloc( sizeof(POINT) );
        if( !_ppt ) return( FALSE );
    
        printf( "   X    Y\n" );
        printf( "---- ----\n" );
        for( indx=0; indx<icount; indx++ ) {        // for each item in LV
          ok = SendMessage( hWndLV, LVM_GETITEMPOSITION, indx, (LPARAM)_ppt );
          ok = ReadProcessMemory( hProcess, _ppt, &pt, sizeof(POINT), &nr );
          printf( "%4d %4d\n", pt.x, pt.y );
        }
    
        ok = expFree( _ppt );
    
        return( TRUE );
        //r Returns TRUE on success
    }
    

    移动项目的函数

    资源管理器实用程序函数

    // EXPLORER UTILITY FUNCTIONS
    
    //@ Allocate a block of memory in explorer space
    void *
    expAlloc(
      int size)     // size of block
    {
        void *p;
    
        p = VirtualAllocEx( 
            hProcess,
            NULL,
            size,
            MEM_COMMIT, 
            PAGE_READWRITE );
        return( p );
        //r Returns addr of memory in EXPLORER space or NULL on error
    }
    
    //@ Free virtual memory in EXPLORER space
    int
    expFree(
      void *p)  // pointer to free
    {
        int ok;
        ok = VirtualFreeEx( hProcess, p, 0, MEM_RELEASE );
        return( ok );
        //r Returns TRUE on success, else FALSE
    }
    
    static int  aBiggest;       // biggest area so far
    static HWND hWndBiggest;    // hWnd with biggest area
    
    //@ Find main list view of explorer
    HWND
    expGetListView()
    {
        //n Approach: Enumerate all child windows of desktop and find largest.
        //n This will be the main explorer window.
    
        HWND hWndDesktop;
        hWndDesktop = GetDesktopWindow();
        if( !hWndDesktop ) return( NULL );
    
        aBiggest    = -1;       // init
        hWndBiggest = NULL;     // init
        EnumChildWindows( hWndDesktop, CallbackDesktopChild, 0 );
        
        return( hWndBiggest );
        //r Returns hWnd of largest explorer list view
    }
    
    //@ Callback for EnumChildWindows
    BOOL CALLBACK CallbackDesktopChild(
      HWND hWnd,
      LPARAM dwUser)
    {
        //n Get size of child. If biggest, save hWnd.
    
        int i,w,h,a;
        char classname[MAXPATH+1];
        RECT rect;
    
        i = GetClassName( hWnd, classname, MAXPATH );   // get class
        if( stricmp( classname, "SysListView32" ) ) {   // not a list view?
          return( TRUE );               // skip it
        }
    
        // CALC SIZE
        i = GetWindowRect( hWnd, &rect );
        w = rect.right - rect.left;
        h = rect.bottom - rect.top;
    
        // CHECK IF BIGGEST
        a = w * h;
        if( a > aBiggest ) {    // is biggest?
          aBiggest    = a;
          hWndBiggest = hWnd;
        }
    
        return( TRUE );     // TRUE to continue enumeration
    }
    
    
    //@ Get process handle of explorer.exe
    HANDLE
    expGetProcessHandle()
    {
        //n Approach: take process snapshot and loop through to find "explorer.exe"
        //n Needs tlhelp32.h and comctl32.lib
        
        int i,stat;
        PROCESSENTRY32 pe;
        HANDLE hSnapshot;
        char *name;
        HANDLE h;
    
        // TAKE A SNAPSHOT
        hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
        if( !hSnapshot ) return( NULL );
    
        // LOOP THROUGH PROCESSES AND FIND "explorer.exe"
        for( i=0;;i++ ) {
          pe.dwSize = sizeof( PROCESSENTRY32 );
          if( i == 0 ) stat = Process32First( hSnapshot, &pe );
          else         stat = Process32Next ( hSnapshot, &pe );
          if( !stat ) break;                // done or error?
          name = pe.szExeFile;
          if( !stricmp( name, "explorer.exe" ) ) {  // matches?
            h = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID ); 
            return( h );
          }
        }
    
        return( NULL );
        //r Returns explorer process handle or NULL on error
    }
    
    //@ Get count of items in explorer list view
    int
    expGetItemCount()
    {
        int count;
    
        count = SendMessage( hWndLV, LVM_GETITEMCOUNT, 0, 0 );
        return( count );
        //r Returns count of item
    }
    
    //@ Get position of list view icon by index
    int
    expGetItemPosition(
      int indx, // index of item
      int *x,   // ptr to int to recv x
      int *y)   // ptr to int to recv y
    {
        int i,ok,icount;
        char classname[MAXPATH+1];
        POINT pt;                   // point in app space
        POINT *_ppt;                    // point in exp space
        int nr;                     // count of bytes read
        //int w,h;
    
        i = GetClassName( hWndLV, classname, MAXPATH );
    
        // GET COUNT OF ITEMS IN LIST VIEW
        icount = expGetItemCount();
        if( indx < 0 || indx >= icount ) return( FALSE );
    
        // ALLOC POINT IN EXP SPACE
        _ppt = expAlloc( sizeof(POINT) );
        if( !_ppt ) return( FALSE );
    
        // SEND MESSAGE TO GET POS INTO EXP SPACE POINT
        ok = SendMessage( hWndLV, LVM_GETITEMPOSITION, indx, (LPARAM)_ppt );
        if( !ok ) return( FALSE );
    
        // READ EXP SPACE POINT INTO APP SPACE POINT
        ok = ReadProcessMemory( hProcess, _ppt, &pt, sizeof(POINT), &nr );
        if( !ok ) return( FALSE );
    
        ok = expFree( _ppt );
        if( !ok ) return( FALSE );
    
        if( x ) *x = pt.x;
        if( y ) *y = pt.y;
    
        //r Returns TRUE on success
        return( TRUE );  
    }  
    
    //@ Move item
    int
    expSetItemPosition(
      char *name,   // icon name
      int x,        // new x coord
      int y)        // new y coord
    {
        int ok,indx;
        LPARAM lParam;
    
        indx = expGetItemIndex( name );
        if( indx < 0 ) return( FALSE );
    
        lParam = MAKELPARAM( x, y );
        ok = SendMessage( hWndLV, LVM_SETITEMPOSITION, indx, lParam );
        if( !ok ) return( FALSE );
    
        return( TRUE );
        //r Returns TRUE on success
    }
    

    WIN10附录

    在Win10下,解决方案要复杂得多。你必须使用各种COM对象和接口,例如IShellWindows等(天哪,我讨厌COM)。我没有创建一个库,而是提供了一个完整的工作程序下面。我用MSVC 2019编译了这个。为了清楚起见,省略了错误检查(但您应该这样做)。

    //  icons.cpp - Display (and optionally move) desktop icons
    
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <ShlObj.h>
    #include <atlbase.h>
    
    int
    main(int argc,char** argv)
    {
        CComPtr<IShellWindows> spShellWindows;
        CComPtr<IShellBrowser> spBrowser;
        CComPtr<IDispatch> spDispatch;
        CComPtr<IShellView> spShellView;
        CComPtr<IFolderView>  spView;
        CComPtr<IShellFolder> spFolder;
        CComPtr<IEnumIDList>  spEnum;
        CComHeapPtr<ITEMID_CHILD> spidl;
        CComVariant vtLoc(CLSID_ShellWindows);
        CComVariant vtEmpty;
        STRRET str;
    
        int count=0;
        HRESULT hr;
        long lhWnd;
    
        // INITIALIZE COM
        CoInitialize(NULL);
        
        // GET ShellWindows INTERFACE
        hr = spShellWindows.CoCreateInstance(CLSID_ShellWindows);
    
        // FIND WINDOW
        hr = spShellWindows->FindWindowSW(
            &vtLoc, &vtEmpty, SWC_DESKTOP, &lhWnd, SWFO_NEEDDISPATCH, &spDispatch);
    
        // GET DISPATCH INTERFACE
        CComQIPtr<IServiceProvider>(spDispatch)->
          QueryService(SID_STopLevelBrowser, IID_PPV_ARGS(&spBrowser));
    
        spBrowser->QueryActiveShellView(&spShellView);
        spShellView->QueryInterface(IID_PPV_ARGS(&spView) );
    
        hr = spView->GetFolder(IID_PPV_ARGS(&spFolder));
    
        // GET ENUMERATOR
        spView->Items(SVGIO_ALLVIEW, IID_PPV_ARGS(&spEnum));    // get enumerator
    
        // ENUMERATE ALL DESKTOP ITEMS
        for (; spEnum->Next(1, &spidl, nullptr) == S_OK; spidl.Free()) {
          // GET/PRINT ICON NAME AND POSITION
          char* name;
          POINT pt;
          spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
          StrRetToStr(&str, spidl, &name);
          spView->GetItemPosition(spidl, &pt);
          printf("%5d %5d \"%s\"\n", pt.x, pt.y, name);
    
    #define MOVE_ICON
    #ifdef MOVE_ICON
          // OPTIONAL: MOVE *SINGLE* SELECTED ITEM
          {
            if( !_stricmp(name, "ICON_NAME_TO_MOVE") ) {
            PCITEMID_CHILD apidl[1] = { spidl };
            int numitems = 1;
            // SET pt TO NEW POSITION HERE
            hr = spView->SelectAndPositionItems(numitems, apidl, &pt, 0);
            }
          }
    #endif
    
          count++;
        }
        CoUninitialize();           // release COM
    
        fprintf(stderr, "enumerated %d desktop icons\n", count);
        fprintf(stderr, "Press any key to exit...\n");
        _getch();
        exit(0 );
    }