But- "MultiSelectModel" should enable me to select multiple files in Explorer, invoke my action from context menu and pass all those files to a single instance of my program. But it opens as many copies of my program as files selected in Explorer.
If you read the MSDN documentation:
How to Employ the Verb Selection Model, you would see that you are registering the "MultiSelectModel" value in the wrong Registry key. It belongs in the verb key, not in the verb's "Command" key.
Also, per other MSDN documentation:
HKEY_CLASSES_ROOT key, you should NOT write directly to
HKEY_CLASSES_ROOT at all. Write to either "HKEY_LOCAL_MACHINE\Software\Classes" (all users) or "HKEY_CURRENT_USER\Software\Classes" (current user) instead.
Try this:
RootKey := HKEY_CURRENT_USER; // or HKEY_LOCAL_MACHINE
APP_NAME := 'MyProg';
if OpenKey('\Software\Classes\*\shell\' + APP_NAME, true) then
begin
WriteString('', 'Action with My Prog');
WriteString('MultiSelectModel', 'Player');
if OpenKey('Command', true) then
WriteString('', '"' + Application.ExeName + '" c "%1"');
end;
Now, that being said, this will still not do what you want. It will still invoke your "command" separately for each selected file, thus invoking your app multiple times. That is simple enough to handle, by having subsequent instances of your app send each file to an existing instance. But that is not efficient.
When I search my Registry,
every use of "MultiSelectModel" uses either "ExplorerCommandHandler" or "DelegateExecute" to actually handle their commands:
- For "ExplorerCommandHandler", you need to write a COM server that implements the
IExplorerCommand interface, whose
Invoke() method receives multiple files as an
IShellItemArray.
- For "DelegateExecute", you need to write a COM server that implements the
IExecuteCommand and
IObjectWithSelection interfaces. The
IObjectWithSelection::SetSelection() method receives multiple files as an
IShellItemArray, and then
IExecuteCommand::Execute() acts on them.