我试图弄清楚如何获取卷 Guid 路径(例如“ \\?\Volume{50165421-0000-0000-0000-005d25000000}\”)的 PIDL(或 IShellItem 或 IShellFolder)。我希望能够从我的程序或其子对象上调用文件操作或 shell 上下文菜单项。如果它已安装并可通过驱动器号或文件夹访问,没问题,但我正在努力处理未安装的卷。
虽然 Windows 资源管理器的地址栏无法解析这些名称,但可以使用 run 命令(或使用 ShellExecute)打开 Windows 资源管理器:


一旦在 Windows 资源管理器中打开,它就可以很好地处理路径,即枚举和上下文菜单正常工作。
到目前为止我已经尝试过:
实际上,我没有检查很多 IBindCtx 选项,因为从文档中我不确定该用例应该尝试哪些选项。
在这里尝试了 @RbMm 共享的未记录的 IShellURL 接口- 它显示与 AddressBar 相同的错误消息框。
从卷管理参考中,我也没有看到 PIDL 的连接点。
使用带有 Process Monitor 的 ShellExecute 跟踪卷名称的开头,我看到 Windows 资源管理器正在访问
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\?\Volume{50165421-0000-0000-0000-005D25000000},就在打开“ \Device\HarddiskVolume3\”之前。但我什至不确定这是否相关。
有谁知道我还可以尝试什么?
据我了解,目前有两种方法可以使用资源管理器从 Shell 命名空间扩展复制虚拟文件,以便向用户显示复制 GUI:
通过IDataObject接口:
读取文件是通过至少IDataObject::GetData支持CFSTR_FILEDESCRIPTORW,CFSTR_FILECONTENTS和剪贴板格式来完成的。CFSTR_SHELLIDLIST请求应创建一个用于访问数据的对象CFSTR_FILECONTENTS。当需要时,通过设置标志来启用 UI 。IDataObject::GetDataIStreamFD_PROGRESSUICFSTR_FILEDESCRIPTORW
通过ITransferSource接口:
读取文件是通过ITransferSource::OpenItem请求IShellItemResources. 然后IShellItemResources应将{4F74D1CF-680C-4EA3-8020-4BDA6792DA3C}资源报告为受支持(GUID 指示该项目有一个 IStream)。最后,IStream通过父级请求ShellFolder::BindToObject访问数据。UI 由资源管理器本身处理,它始终显示。
我的问题是:这两种机制单独工作得很好(正如您从屏幕截图中看到的)。但是一旦我启用了IDataObjectfromIShellFolder::GetUIObjectOf和ITransferSourcefrom IShellFolder::CreateViewObject- 总是使用 via 方法IDataObject,导致旧的副本 GUI(如第一个屏幕截图所示)。我从跟踪日志中看到ITransferSource多次请求,但没有执行任何操作,它只是立即释放并销毁。
那么,当从 Shell 命名空间扩展进行复制时,如何强制资源管理器显示精美的复制 GUI?
可以在这里找到最小的可重现示例:https://github.com/BilyakA/SO_73938149
在研究最小可重复示例时,我设法使其在启用IDataObject和ITranfserSource接口的情况下按预期工作。事情发生在之后:
regsvr32 /u …winapi windows-shell shell-extensions shell-namespace-extension
语言:C#2.0或更高版本
当用户右键单击某些文件时(我的情况是*.eic),我想注册上下文处理程序来创建菜单.从这些菜单中注册,注销(清理)和处理事件(点击)的过程是什么?
我有一个线索,它与Windows注册表有关,但考虑到.net中有多少东西,如果有方便的方法来做到这一点干净和简单,我不会感到惊讶.
代码片段,网站引用,评论都很好.请把它们扔给我.
显然,在托管语言中创建上下文菜单存在一些问题,正如一些用户所评论的那样.有没有其他优选的方法来实现相同的行为,或者我应该花时间研究这些变通方法?我根本不介意这样做,我很高兴人们已经努力使这成为可能 - 但我仍然想知道是否有一个"适当/干净"的方式实现这一目标.
根据我所看到的一切,当我在应用程序窗口中单击鼠标左键时,以下C++程序应该从托盘图标显示气球工具提示,但它不起作用.谁能告诉我我错过了什么?
这是在XP的Shell32.dll 6.0版本(用DllGetVersion验证).
谢谢!
#include "stdafx.h"
#include "shellapi.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "sysTrayTest";
RegisterClass(&wc);
HWND hWnd = CreateWindow("sysTrayTest", "",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 500, 500,
NULL, NULL, hInstance, NULL);
if (hWnd)
{
ShowWindow(hWnd, nCmdShow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); …Run Code Online (Sandbox Code Playgroud) 我如何编写新的Windows Vista Shell?
我想知道哪些是您作为开发人员使用的最常见(也是最有用的)shell扩展.我打赌列表上有以下内容,但我想知道你要添加的其他内容:
还有其他值得一提吗?
我正在尝试为自定义文件类型编写Windows资源管理器缩略图处理程序.我已经将这个工作正常用于预览窗格,但是很难让它用于缩略图.
Windows似乎甚至没有尝试调用DllGetClassObject入口点.
在继续之前,请注意我使用的是Windows 7和非托管C++.
我在注册表中注册了以下值:
HKCR\CLSID\<my guid>
HKCR\CLSID\<my guid>\InprocServer32 (default value = path to my DLL)
HKCR\CLSID\<my guid>\InprocServer32\ThreadingModel (value = "Apartment")
HKCR\.<my ext>\shellex\{E357FCCD-A995-4576-B01F-234630154E96} (value = my guid)
Run Code Online (Sandbox Code Playgroud)
我也试过使用Win SDK示例,但这不起作用.还有本文中的示例项目(http://www.codemonkeycodes.com/2010/01/11/ithumbnailprovider-re-visited/),但这不起作用.
我是shell编程的新手,所以不确定调试它的最佳方法.我已经尝试将调试器附加到explorer.exe,但这似乎不起作用(断点被禁用,并且我的OutputDebugStrings都没有显示在输出窗口中).请注意,我尝试在WinSDK文档中描述的用于调试shell的注册表中设置"DesktopProcess",但我仍然只在任务管理器中看到一个explorer.exe - 所以"可能"就是为什么我不能调试它?
任何有关这方面的帮助将不胜感激!
问候,丹.
如何为特定文件夹中的文件/文件夹创建上下文菜单.
假设有一个目录"D:\ RandomCodes"
如何为此内的任何文件/文件夹创建自定义上下文菜单项"在MyApp中打开"?此菜单项不应出现在任何其他目录中.我知道如果我在HKCR/Directory/Shell中添加该条目,它将起作用,但随后它将出现在所有文件和文件夹中.请指导我完成这个.
在Windows 7上,是否可以创建要在任务栏中显示的应用程序?我想到的是一个小小部件,如媒体播放器或天气小部件等.
类似于下面的模型:

任何的想法?
有人能告诉我为什么在Windows中运行shell命令拒绝权限以及如何解决?
function executeCommands(inputparms)
{
var oShell = new ActiveXObject("Shell.Application");
var commandtoRun = "C:\\WINDOWS\\Notepad.exe";
if (inputparms != "")
{
var commandParms = document.Form1.filename.value;
}
oShell.ShellExecute(commandtoRun, commandParms, "", "open", "1");
}
Run Code Online (Sandbox Code Playgroud) windows-shell ×10
winapi ×4
c++ ×3
windows ×2
.net ×1
c# ×1
com ×1
contextmenu ×1
javascript ×1
notifyicon ×1
provider ×1
taskbar ×1
thumbnails ×1
tooltip ×1
windows-7 ×1