0

I am developing windows file manager application, essentialy it wraps IExplorerBrowser giving me exact controls as you would have in your Windows explorer.

I've implemented single instance using Mutex and IPC for passing arguments.

So now I wanted to be able to register my file manager as default application when you open directory from ie. desktop

So I created registry script like this:

REGEDIT4

[HKEY_CURRENT_USER\Software\Classes\Drive\shell]
@="AppName"

[HKEY_CURRENT_USER\Software\Classes\Drive\shell\AppName]
@="Open in AppName"

[HKEY_CURRENT_USER\Software\Classes\Drive\shell\AppName\command]
@="\"<app-path>\" %1"

[HKEY_CURRENT_USER\Software\Classes\Directory\shell]
@="AppName"

[HKEY_CURRENT_USER\Software\Classes\Directory\shell\AppName]
@="Open in AppName"

[HKEY_CURRENT_USER\Software\Classes\Directory\shell\AppName\command]
@="\"<app-path>\" \"%1\""

It works as expected, if I double click directory it starts my app, and since I implemented single instance it doesn't spawn more than one instance.

Since I have tabbed interface in my app, every time you open directory it creates new tab with IExplorerBrowser control.

The problem is, now the IExplorerBrowser control behaviour has changed, when I open directory from control I get new tab instead of navigating inside control, which is logical (It always calls registry command for starting my app with direcotry as arg)

TL; DR;

How does windows explorer handle this? How does windows explorer know if directory was opened from ie. desktop, or from inside Windows explorer so that it navigates inside "listview" instead of opening new window?

formatc
  • 4,261
  • 7
  • 43
  • 81
  • 1
    Explorer queries IObjectWithSite interface from IContextMenu of folder and calls IObjectWithSite.SetSite with object implements IServiceProvider. Open command handler uses site and gets IShellBrowser interface. If IShellBrowser is found Open command handler uses it for navigation. – Denis Anisimov Apr 05 '15 at 20:05
  • @DenisAnisimov I'm using this [Windows-API-Code-Pack-1.1](https://github.com/aybe/Windows-API-Code-Pack-1.1/blob/master/source/WindowsAPICodePack/Shell/ExplorerBrowser/ExplorerBrowser.cs) C# implementation of IExplorerBrowser , if I understood you correctly HResult Microsoft.WindowsAPICodePack.Controls.IServiceProvider.QueryService should return HResult.Ok for RIID and interface pointer? – formatc Apr 06 '15 at 11:32

2 Answers2

1

I am not C# developer and I don`t know Windows-API-Code-Pack-1.1 details. In my NSE project I am using the following algorithm of navigation in current Explorer window (part of IContextMenu handler):

Site.QueryInterface(IServiceProvider, ServiceProvider) // Site was received in IObjectWithSite.SetSite
ServiceProvider.QueryService(SID_STopLevelBrowser, IShellBrowser, ShellBrowser)
ShellBrowser.BrowseObject(ChildItem, SBSP_RELATIVE or SBSP_SAMEBROWSER)

Maybe it will help you.

Denis Anisimov
  • 3,297
  • 1
  • 10
  • 18
  • I think I finally understand, you were talking about something similar to this http://stackoverflow.com/questions/28166945/getting-the-results-of-an-explorer-shell-search-in-a-program-that-was-launched-f , basically saying I have to create shell extension and not just shove it in registry. You really helped me alot, thank you! – formatc Apr 07 '15 at 09:56
  • I Created shell extension like you explained in question I linked to in my previous comment, and I get site which implements IServiceProvider in my SetSite function, one more thing that I am going crazy about is that I can't get it to call my InvokeCommand when I double click folder in explorer while it works on right click -> open, any ideas? – formatc Apr 07 '15 at 19:09
  • Do I understand you correctly - when you double click on folder your shell extension is created but IObjectWithSite.SetSite is not called? – Denis Anisimov Apr 08 '15 at 04:02
  • IObjectWithSite.SetSite is called as you said, but InvokeCommand isn't called when I double click. – formatc Apr 08 '15 at 06:15
  • It means your menu item IS NOT FIRST DEFAULT menu item. When you double click on folder first default item is executed. – Denis Anisimov Apr 08 '15 at 08:41
  • Do you use Directory regkey or Folder regkey for context menu shell extension registration? I recommend Folder. – Denis Anisimov Apr 08 '15 at 09:12
  • Yes, I used Directory regkey, I set MFS_DEFAULT, returned "open", created MayChangeDefaultMenu subkey. One thing I'm not sure was how to handle CMF_DEFAULTONLY, maybe thats the problem? – formatc Apr 08 '15 at 09:35
  • Why not Folder subkey? It has more importance. What happens then you double click folder? Could you show screenshot of context menu? – Denis Anisimov Apr 08 '15 at 10:13
0

It has to be a better way to do this, but this works:

  HResult ICommDlgBrowser3.OnDefaultCommand(IntPtr ppshv)
    {
        if (SelectedItems.Count > 0)
        {
            var item = SelectedItems[0];

            ShellNativeMethods.ShellFileGetAttributesOptions sfgao;
            item.NativeShellItem2.GetAttributes(ShellNativeMethods.ShellFileGetAttributesOptions.Folder, out sfgao);
            bool isFolder = (sfgao & ShellNativeMethods.ShellFileGetAttributesOptions.Folder) != 0;

            if (isFolder)
            {
                Navigate(SelectedItems[0]);
                return HResult.Ok;
            }
        }
        return HResult.False;
    }
formatc
  • 4,261
  • 7
  • 43
  • 81