IExplorerBrowser - 在不启动默认应用程序的情况下浏览到位

时间:2015-04-05 12:13:46

标签: c# winapi registry windows-explorer single-instance

我正在开发Windows文件管理器应用程序,实际上它包装了IExplorerBrowser,为我提供了与Windows资源管理器中一样的精确控件。

我使用Mutex和IPC实现了单个实例来传递参数。

所以现在我希望能够在从ie打开目录时将我的文件管理器注册为默认应用程序。桌面

所以我创建了这样的注册表脚本:

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\""

它按预期工作,如果我双击目录它启动我的应用程序,并且因为我实现单个实例它不会产生多个实例。

由于我的应用程序中有选项卡界面,因此每次打开目录时都会使用IExplorerBrowser控件创建新选项卡。

问题是,现在IExplorerBrowser控件的行为发生了变化,当我从控件中打开目录时,我得到了新的选项卡,而不是在内部控件中导航,这是合乎逻辑的(它总是调用注册表命令以启动我的应用程序,并将其作为arg)< / p>

TL; DR;

Windows资源管理器如何处理这个问题? Windows资源管理器如何知道目录是否从ie打开。桌面,或从Windows资源管理器内部导航,以便在“listview”内导航而不是打开新窗口?

2 个答案:

答案 0 :(得分:1)

我不是C#开发人员,我不知道Windows-API-Code-Pack-1.1的详细信息。在我的NSE项目中,我在当前的Explorer窗口中使用了以下导航算法(IContextMenu处理程序的一部分):

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

也许它会帮助你。

答案 1 :(得分:0)

这必须是更好的方法,但这有效:

  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;
    }