How to enumerate PropertySheet shell extension associated with extension - winapi

I want to fill a list with the PropertySheet shell extensions associated with a file extension. I found the SHGetAssocKeys() function and it looks like it allows me to enumerate all HKEYs associated with the file extension and I can read all shellex\PropertySheetHandlers values. But this function is only available on Windows 8. What about XP, Vista and 7? Is there any official way?
UPDATE
I want to get list of HKEY like this:
HKCR\MyProgID\shellex\PropertySheetHandlers
HKCR\SystemFileAssociations\.MyExt\shellex\PropertySheetHandlers
HKCR\SystemFileAssociations\MyPercivedType\shellex\PropertySheetHandlers
HKCR\*\shellex\PropertySheetHandlers
HKCR\AllFilesystemObjects\shellex\PropertySheetHandlers

Related

How do I use one of the standard windows icons via the Win32 API?

For an app-supplied icon I know I can use LR_LOADFROMFILE, LR_DEFAULTSIZE flags with user32.LoadImageA, but for now I want to use one of the standard windows supplied ones, I think they live in a win32 dll somewhere (maybe user32 itself).
How do I use one of the standard windows icons via the Win32 API?
Call LoadIcon to load one of the standard icons. You must pass NULL as the instance and the one of the predefined values IDI_ERROR, IDI_QUESTION, etc. See the documentation for the full list.

Shell namespace extension adding barricade

I implemented namespace extension using default shell view in Windows XP.
Everything works fine, but I want add barricade (A Description of Protected Folders - also applicable to Windows XP).
Is possible this using documented/undocumented functions (SFVM messages), or this feature is hard-coded ?
If you fill all data for your extension view yourself, then you can read contents of hidden (or any other) folders on your own and display them straightaway, or hide if it needs to.
Your extension uses its own namespace, which is not controlled by the built-in shell protection options.
P.S. Starting from Windows 7+ it should not be a problem.

Coerce Windows to show a thumbnail for my custom file type

I want to use the windows OpenFileDialog class in C# to browse files for my application. I would then like the files to show up with previews in Windows' "thumbnails" view.
Is there a simple way to make this happen? I'm thinking there should be a way to encode the files so that Windows simply reads and displays the thumbnail information, even though it's an unsupported file type?
I know Windows Vista has a different interface (IThumbnailProvider as opposed to IExtractImage) than Windows XP, but I need it to work across platforms.
Thanks!
/ Jakob
You have to write a Shell Extension Handler Thumbnail Image Extractor. This is unmanaged c++ code that extracts the image from your custom filetype to display within explorer shell. You can find more about Shell Extension Handlers at the following link:
Creating Shell Extension Handlers

How does Windows associate icons to files in explorer shell?

I have both InDesign CS2 and CS3 installed. Both use files with .indd extension. How does Windows know which icon to use? It uses correct icons i.e. CS2 files have cs2 icon and CS3 files have CS3 icon.
How does Windows know how to do this?
And how can I extract or use this version-detection system in my programs?
Edit:
Thank you for your shell-extension-icon-handler answers. Something new to me. But is there any way I could connect to IconHandler that InDesign provides and use it to detect version of the InDesign file?
You need to write an Icon Handler shell extension. See the MSDN documentation for IExtractIcon. The basic mechanism is that you create a shell extension and register the icon handler for the file type you want (look in HKEY_CLASSES_ROOT/.indd) and then the shell loads your handler, passes the file information and requests an icon in return. There's also the IExtractImage method if you want to provide a thumbnail bitmap rather than just an icon.
Note that you need to be especially careful writing shell extension handlers as any memory leaks or crashes can nuke the explorer and any other applications that display a file open/save dialog.
For some files it's HKEY_CLASSES_ROOT\<file extension here>\DefaultIcon registry entry, but most files map to a more friendly name, e.g. .pdf\(Default) -> AcroExch.Document (if Adobe Reader is installed).
In that case you have to go along the registry to AcroExch.Document and see that either
DefaultIcon is right there or
AcroExch.Document\CLSID\(Default) is some GUID. Then, follow HKEY_CLASSES_ROOT\CLSID\<insert that guid here> and you'll notice that this key contains DefaultIcon
... and DefaultIcon is where the icon is loaded from.
Hope that was clear enough ;). I don't know about your special case but there should be a distinction in the registry.
It almost certainly installs a shell icon extension handler. Writing your own and knowing how to detect the version in a file format that isn't documented well or at all is quite tricky.

How does the OS know what to do with a file when the "Open With..." option is selected?

Explanation:
I don't remember about Linux and I don't know about OS X, but in Windows you can right-click a file and select a program to open it. But how does the OS know exactly how to make the program open it? Does it keep track of the "Open file" dialogs the program has? Does the developer have to specify a special event handler or something for these cases?
For Windows, the answer is in the registry. If you're comfortable reading the registry, run regedit.exe on your Windows machine.
Under HKEY_CLASSES_ROOT, you will see a key list of all file types, .doc, .txt, etc. Each of these keys contains a key called "OpenWithList" or "OpenWithProgIds". An application may have a registered "ProgId", also found under HKEY_CLASSES_ROOT, and it can register it's ProgId to the file types it wants to handle in OpenWithProgIds. Otherwise it registers itself in OpenWithList.
In response to the comment to the first answer (cos I don't have enough rep to comment):
You're thinking of DDE, which is a near-enough deprecated technology. The Windows shell executes the application with the selected file as the first parameter.
The Windows Explorer remembers your previous "Open With..." choices based on file extension in the following key:
HKCR\.ext\OpenWithList
Next time you right-click the file, it looks there and build a list of programs you have previously used to open a particular file type.
Say it finds a key named "myapp.exe". It then looks up the application here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\myapp.exe
fetches the info where the application is installed. And it goes here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\myapp.exe
follows the GUID stored there to find out the display name of the application.
To add to the fun, the primary associated application is in the list as well, also everything in the OpenWithProgIds key and everything in:
HKEY_CLASSES_ROOT\*\OpenWithList
as well as their respective HKEY_CURRENT_USER counterparts.
The resulting list of applications is then made unique, sorted and displayed. On selection the file is started like any other file you click on - i.e.:
C:\path\to\myapp.exe "C:\path\to\the\file.ext"
http://windowsxp.mvps.org/OpenWith.htm
File associations are stored in the Registry in: HKEY_CLASSES_ROOT.
You can manage them graphically by using Windows Explorer: (WinXP)
Click Tools/Options/File Types
Or with the "Default Programs" applet in Control Panel. (Vista)
Just for some nostalgia the rather brilliant Acorn archimedes had a much better system with each file type having a unique type number, with a manufacturer and application code (rather like a MAC address) which was written with the file.
This means you can have different files all called .bak opened by the correct application - unlike the windows case where a new installed app steals the ownership of every exiting file of that type. Autocad is especialy bad for this, registering about 20 file types.
The operating system runs the specified program sending as parameter the path of the file to open.
For example, in C#, if you want to know which file the operating system wants you to open you'll need to do:
class Program
{
static void Main(string[] args)
{
if (args.Length == 1) //The OS wants me to open a file
openSomeFileJustBecauseTheOSWantsIt(args[0]);
}
}

Resources