Reading name and location of icons in Desktop using C#

Published on Tuesday, 19 February 2013 23:01

Last week, one of my friends asked me about a way to retrieve list of desktop icons and their location on the screen. But is it even possible to get the list of Icons (not "Files") and also their location on the "Screen"?

Actually Desktop is an application or more clearly, one instance of Explorer.exe; and it is basically a big ListView. So we can access its items and other properties using List View Messages and SendMessage function from user32.dll. A C++ programer could say that this is very easy task to do,

But there are number of problems for writing the same code in C#; first, you need to do a lot of P/Invoke calls, Second, as you need to access the ListView from another process (for example writing an application to show items of desktop which is under Explorer.exe process) any calls to SendMessage method with a Pointer or Object result, gives you an invalid one. The reason of this is because all handles are relative to program position in memory and its different with your application location in memory.

There are number of ways to solve this problem and read other application's memory; One of the ways is to creating a remote thread under that program using CreateRemoteThread and run our code there; Another approach is to create a Hook using EasyHook or similar frameworks and inject it to the victim application; But the easier way is to read the program's virtual space using OpenProcess, WriteProcessMemory and ReadProcessMemory functions from kernal32.dll directly from our application.

Unfortunately there was no working example in C# after hours of Googling. So I started to write my own code and send it to my friend, then sharing it here.

Attached is a class and a sample for above case. It can find ListViews in any process you choose and then it will try to extract item's location and name in that ListView. For example sample application shows icons and their locations at desktop.