IExplorerBrowser - 在不启动默认应用程序的情况下就地浏览
IExplorerBrowser - Browse in place without starting default application
我正在开发 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 控件的行为已经改变,当我从控件打开目录时,我得到了新的选项卡,而不是在控件内部导航,这是合乎逻辑的(它总是调用注册表命令来启动我的应用程序,并将 direcotry 作为 arg )
TL;博士;
windows 资源管理器如何处理这个问题? windows 资源管理器如何知道目录是否从 ie 打开。桌面,或从 Windows 资源管理器内部,以便它在 "listview" 内部导航,而不是打开新的 window?
我不是 C# 开发人员,我不知道 Windows-API-Code-Pack-1.1 的详细信息。在我的 NSE 项目中,我在当前 Explorer window(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)
也许对你有帮助。
它必须是一个更好的方法来做到这一点,但这个有效:
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;
}
我正在开发 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 控件的行为已经改变,当我从控件打开目录时,我得到了新的选项卡,而不是在控件内部导航,这是合乎逻辑的(它总是调用注册表命令来启动我的应用程序,并将 direcotry 作为 arg )
TL;博士;
windows 资源管理器如何处理这个问题? windows 资源管理器如何知道目录是否从 ie 打开。桌面,或从 Windows 资源管理器内部,以便它在 "listview" 内部导航,而不是打开新的 window?
我不是 C# 开发人员,我不知道 Windows-API-Code-Pack-1.1 的详细信息。在我的 NSE 项目中,我在当前 Explorer window(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)
也许对你有帮助。
它必须是一个更好的方法来做到这一点,但这个有效:
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;
}