There are many instances when we would want to get information contained within an EXE application file. Is it a 32-bit or 64-bit application? Is it a .NET or native application? Does the application run with a window or in command line mode? One way to find the architecture without using a tool in Windows is to run it then look through Task Manager’s ‘Processes’ list to see whether the image name ends with ‘* 32′. If it does, then it’s a 32-bit process otherwise not. Another cumbersome way is to download some PE tool and look through and find ‘Magic Number’ field in an EXE’s Optional header (Reference: Microsoft Portable Executable Specification).
Currently, when selecting an EXE file in Windows Explorer, the only information we get is that it’s an ‘Application’ as shown below.
It would be great if we could develop a property handler for Windows Explorer which read the above mentioned properties from within an EXE file and replaced ‘Application’ text with a more useful description like ’32-bit .NET GUI Application’. Taking this further, we could add support for DLL, OBJ, O, LIB and A file extension and display their important properties inside the file manager without having to use any external tool.
Unfortunately, Explorer provides no way for property handlers to modify this text. The source of this text is tied to the registry value:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\exefile : ‘FriendlyTypeName’ Value
This value can be either a string value or redirection string to a path of a Portable Executable file with reference to a string value in its String Table Resource. Neither is the property handler invoked when the user clicks on a PE file in the file manager. This means there is no way to programmatically control this value. Instead, we can control hundreds of properties already provided by Microsoft. Even though the registered schema for a file extension may quote a limited number of supported properties, when the user right clicks on the file manager’s list view header and adds additional properties, Explorer queries property manager for the selected property even though the registered schema may not have stated that the property is supported. I selected ‘System.Comment’ property to subclass because the property title seemed fit for my purpose. Again, developers do no use this property for their EXE files because the original property handler that comes with Windows does not handle this property (according to behavior seen in Windows 7).
The project was named ‘Manta’ (after Manta Ray fish) and I started writing a C++ based COM in-process property handler DLL. I followed MSDN documentation’s recommendation that I implement ‘IInitializeWithStream’ interface rather than ‘IInitializeWithFile’. If I needed the file name associated with the stream, I could call ‘Stat()’ function on the stream (file name returned is without path). This worked fine in Windows 7 SP1 but when deploying to Windows 8, the property handler crashed immediately. It turns out calling ‘Stat()’ on the stream returned a ‘STATSTG’ structure with only type, size and grfMode fields having correct values. All the other fields including ‘pwcsName’ (this field contains a C-string pointer to the file name) were set to NULL. This meant I had to convert ‘IInitializeWithStream’ implementation to ‘IInitializeWithFile’. Fortunately, using ‘SHCreateStreamOnFileEx()’ function I could create a stream from a file path. This meant code that was written need not be changed.
The property handler was now able to respond to Explorer’s request for ‘System.Comment’ property. But the default property handler, implemented properties such as Copyright, Product Name, Version etc. These information are got from Version Information Blocks contained within Version Resource in a Portable Executable. I had two choices – either implement the version information extraction routine using Win API functions myself or find a way to make use of the original property handler for other properties. The second choice seemed more obvious. Windows Property System provides no way of sub classing an existing property handler, so I used a COM technique called delegation. In this technique, my property handler creates a COM object using original handler’s CLSID. When Explorer asks for natively supported properties, my handler forwards it to the original handler. My handler then merely re-returns the return value from original handler. When Explorer asks for ‘System.Comment’ property my handler handles this and does not delegate to the original handler. To properly implement this, my handler had to have access to original handler’s CLSID. I decided that the installer program was responsible for saving original handler’s CLSID in a convenient location were my handler could find it when needed. I built an installer using ‘InnoSetup’ to do this easily.
After installing Manta, the file explorer shows the information as follows:
As you can see, not only have I added a new property but old properties are still handled. Even though we discussed only EXE files, the handler supports DLL, OBJ, O, LIB and A file extensions. Unlike the default handler my handler implements ‘IPropertyStoreCapabilities’ interface so that ‘System.Comment’ property is made read-only removing an annoying faulty handling with previous handler.
One unexpected consequence of implementing this property handler is that now I can use Windows Search to find all PEs which are .NET or which are 32-bit. By typing ‘Comment:32-bit’ on the search box, I can search for all the 32-bit PEs in a folder. Just to make sure the search index (which is used by Windows Search to perform speedy indexed search) has collected this new property for your file, rebuild the index by going to ‘Indexing Options->Advanced->Rebuild’ (Just type ‘Indexing Options’ on your start menu search box to find indexing options).
Finally, if you are making a property handler on your own, make sure that on a 64-bit Windows you implement and install both 32-bit and 64-bit property handler DLLs in their appropriate registry keys. Even though Windows Explorer is a 64-bit process, a 32-bit process browsing properties of a file programmatically will use the default handler and see only the default properties. On a 32-bit architecture, only a 32-bit DLL will suffice.
Registry value for property handler installation:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.<File extension> : (Default) = <CLSID>
Registry value for 32-bit property handler installation in 64-bit Windows:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.<File extension> : (Default) = <CLSID>
Registry key to change what properties to display in the file manager for what view: