Windows桌面快捷方式的位置存储在哪里?
我要问的是图标的屏幕位置而不是实际的图标本身。我知道图标本身存储在各种DLL,EXE等中。这些位置显然存储在某些非易失性存储中,因为它们通过重新引导仍然存在。
我的最终目标是编写一个要显示的应用程序,并有选择地在桌面上重新排列图标。
我知道这是可能的,因为许多可用的应用程序都可以这样做(例如,“ 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`
我编写了一个程序来提取这些内容,但是键值的格式却令人费解。
任何人都知道它们的存储位置和方式吗?
答案 0 :(得分:0)
我终于弄清楚了该怎么做(显示并重新排列桌面图标)。我最初的问题是查找,读取和写入存储图标信息的文件,但这不是一种有用的方法。这是我学到的:
Explorer.exe在巨大的ListView中显示桌面项目,该ListView覆盖了整个桌面,其中ListView项目对应于每个可见图标。在启动时,资源管理器从一些奥秘文件中读取信息,并填充ListView。退出时,它将从ListView重写该文件。因此,修改文件可能没有帮助,因为退出时会被覆盖。
操纵桌面项目的正确方法是直接操纵ListView中的项目。任何更改在更改后立即可见,并在退出时保存。要访问这些项目,我们可以使用一些Windows消息:LVM_GETITEM,LVM_GETITEMCOUNT,LVM_GETITEMPOSITION和LVM_SETITEMPOSITION。这些消息使用起来很简单,但很复杂:有些消息需要指向参数结构的指针。这些结构必须位于我的应用程序的资源管理器的地址空间不是中,因此需要一些技巧。这是操作方法。我以LVM_GETITEMPOSITION为例,它需要一个指向POINT结构的指针。
在您的应用中声明一个POINT结构。
使用API VirtualAllocEx()在资源管理器的地址空间中分配一个镜像结构。
将LVM_GETITEMPOSITION发送到Explorer,以指定指向该结构的指针。
使用API ReadProcessMemory()将结果读回到应用程序的POINT中。此功能可以跨不同的地址空间读取内存。
我已经为这些操作制作了原型,它们可以按我的意愿工作。我的代码很长,但我会在清理后立即发布摘录。
更新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
}
移动项目的功能
请参阅下面的“ expSetItemPosition”。更新10/6/19
资源管理器实用程序功能
// 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
}