gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:40:05 28 4
gpt4 key购买 nike

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

我问的是图标在屏幕上的位置,而不是实际图标本身。我知道图标本身存储在各种 DLL、EXE 等中。这些位置显然存储在一些非 volatile 存储中,因为它们通过重新启动持续存在。

我的最终目标是编写一个应用程序来显示,并可选择在我的桌面上重新排列图标。
我知道这是可能的,因为许多可用的应用程序都可以这样做(例如,“WinTidy”)。

我发现很多关于“Windows Shell Bags”的讨论。关于这些的有趣文章在 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`

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

有人知道它们存放在哪里以及如何存放吗?

最佳答案

20 年 6 月 3 日更新
++++++++++++++++++++++++++++++++++++++++
我刚换了一台Win10 64位的机器,发现下面的解决方法已经不行了。我相信是因为桌面内部结构发生了变化。我想出了如何做到这一点。请参阅此答案末尾的“WIN10 ADDENDUM”。
++++++++++++++++++++++++++++++++++++++++

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

Explorer.exe 在覆盖整个桌面的巨大 ListView 中显示桌面项,ListView 项对应于每个可见图标。在启动时,Explorer 从一些神秘的文件中读取信息并填充 ListView。退出时,它会从 ListView 重新写入该文件。因此修改文件没有帮助,因为它会在退出时被覆盖。

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

  • 在您的应用中声明一个 POINT 结构。

  • 使用 API VirtualAllocEx() 在 Explorer 的地址空间中分配一个镜像结构。

  • 将 LVM_GETITEMPOSITION 发送到资源管理器,指定指向此结构的指针。

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

我已经对这些操作进行了原型(prototype)设计,它们按我想要的方式工作。我的代码很长,但我会在清理后立即发布摘录。

2019 年 10 月 4 日更新 ----------------------------------

代码摘录

创建了一组常用的实用函数,使代码更加紧凑和可读。这些被命名为“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
}

移动项目的功能
请参阅下面的“expSetItemPosition”。 2019 年 10 月 6 日更新

Explorer 实用函数

// 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 附录20/6/19
++++++++++++++++++++++++++++++++++++

在Win10下,解决方法就复杂多了。您必须使用各种 COM 对象和接口(interface),例如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 );
}

关于windows - 桌面快捷方式的位置存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58126669/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com