一旦我的安装程序完成应用程序 exe 新版本的安装,我想告诉资源管理器使用新 exe 的图标作为其快捷方式。但是,我不知道该怎么做。
从网上看,问题似乎是系统图像列表缓存了旧版本的图标。我尝试使用参数调用SHChangeNotifySHCNE_UPDATEIMAGE。我尝试致电SHUpdateImage。我什至尝试过大锤式的广播方式WM_SETTINGCHANGE。似乎什么都不起作用。
完全有可能我只是做错了什么。任何帮助,将不胜感激。
警告:下面是非常丑陋的测试代码。
#if 1
// First attempt: using shell functions
wchar_t icon_path[MAX_PATH];
int icon_index;
UINT icon_flags;
IShellFolder *desktop_folder;
IShellFolder *sub_folder;
IExtractIcon *extract_icon;
LPITEMIDLIST pidl;
SHGetDesktopFolder(&desktop_folder);
wchar_t *folder_path = L"C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\MyCompany\\";
desktop_folder->ParseDisplayName(NULL, NULL, folder_path, NULL, &pidl,
NULL);
desktop_folder->BindToObject(pidl, NULL, IID_IShellFolder,
(void**) &sub_folder);
sub_folder->ParseDisplayName(NULL, NULL, L"MyApp.lnk", NULL, &pidl,
NULL);
sub_folder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*) &pidl,
IID_IExtractIcon, NULL, (void**) &extract_icon);
extract_icon->GetIconLocation(0, icon_path, MAX_PATH,
&icon_index, &icon_flags); …Run Code Online (Sandbox Code Playgroud)
网络卷的名称可以更改。
我把名字改成了脊椎盘

要更改网络名称,我会
它有效,但有时即使我使用 SHChangeNotify 和 WM_DEVICECHANGE 也无效。有时,新名称不会应用到 Windows 资源管理器中。
但是,如果我终止 Explorer 并重新执行,则会应用该名称。
我正在寻找一个刷新Windows资源管理器的界面。(语法正确吗?对不起,我不能很好地表达这句话。)
有没有合适的功能?资源管理器应重新读取注册表并刷新。
我看到一个应该做这个比较PIDL或者:的IShellFolder :: CompareIDs().
特别是,我试图检测给定的绝对PIDL(或相对)是否是控制面板的绝对值.
然而,在实践中我最终得到两个PIDL,其中IShellFolder :: CompareIDs()声称不相等,当它们应该是(查看每个的GetDisplayName(),我可以看到我们确实在看控制面板) .
基本上,我通过以下方式获得控制面板的绝对PIDL:
PIDL iidControlPanel = nullptr;
SHGetSpecialFolderLocation(hwnd, CSIDL_CONTROLS, &iidControlPanel);
Run Code Online (Sandbox Code Playgroud)
然后比较传入的枚举shell对象(参见此处的上下文 - 简而言之,这是查看枚举CMFCShellTreeCtrl中的桌面shell命名空间的结果):
bool bIsControlPanel = CompareAbsolutePIDLs(iidControlPanel, pItem->pidlFQ);
Run Code Online (Sandbox Code Playgroud)
作为参考,这是比较功能:
bool CompareAbsolutePIDLs(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
{
CComPtr<IShellFolder> ishDesk;
SHGetDesktopFolder(&ishDesk);
HRESULT hr = ishDesk->CompareIDs(SHCIDS_CANONICALONLY, pidl1, pidl2);
return SUCCEEDED(hr) && HRESULT_CODE(hr) == 0;
}
Run Code Online (Sandbox Code Playgroud)
在调试器中,我可以看到每个返回的GetDisplayName():
"::{26EE0668-A00A-44D7-9371-BEB064C98683}\0"
"::{26EE0668-A00A-44D7-9371-BEB064C98683}"
Run Code Online (Sandbox Code Playgroud)
在这里你可以看到PIDL的十六进制转储:
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *0c* 00
1f 70 68 06 ee …Run Code Online (Sandbox Code Playgroud) 给定一些文件(或 shell 文件对象),我如何使用.MAPIMail它们调用注册的 shell 扩展处理程序?
我的计算机上有一些文件:
C:\Users\ian\AppData\Local\Temp\Contoso_Invoice_141174.pdfC:\Users\ian\AppData\Local\Temp\Contoso_Invoice_141173.pdfC:\Users\ian\AppData\Local\Temp\Contoso_Invoice_141171.pdf我想做的编程相当于将它们放在.MAPIMail注册的处理程序上:

发送到文件夹的邮件收件人选项实际上是一个特殊的注册.MAPIMail扩展:

这是在系统上注册的文件类型:
HKEY_CLASSES_ROOT\.mapimail
Run Code Online (Sandbox Code Playgroud)
如何调用临时.mapimail文件上的放置?
现在,我可能是一个糟糕的开发人员,并且拼写了注册表,该条目的.mapimail默认值:
CLSID\{9E56BE60-C50F-11CF-9A2C-00A0C90A90CE}
Run Code Online (Sandbox Code Playgroud)
提取 clsid {9E56BE60-C50F-11CF-9A2C-00A0C90A90CE},并确认该类已注册:
HKEY_CLASSES_ROOT\CLSID\{9E56BE60-C50F-11CF-9A2C-00A0C90A90CE}
(default) = Desktop Shortcut
\InProcServer32
(default) = %SystemRoot%\System32\sendmail.dll
Run Code Online (Sandbox Code Playgroud)
并用于CoCreateInstance创建该 COM 对象:
IUnknown unk = CreateComObject("{9E56BE60-C50F-11CF-9A2C-00A0C90A90CE}");
Run Code Online (Sandbox Code Playgroud)
然后我处于一个无文档、不受支持的世界,我不知道我必须使用什么接口QueryInterface,也不知道以什么顺序调用什么方法。
我想要的是可能涉及外壳的东西(伪代码):
IShellFolder desktop;
OleCheck(SHGetDesktopFolder(out desktop));
List<pidl> pidls = new List<pidl>();
ULONG chEaten = 0;
ULONG dwAttributes = …Run Code Online (Sandbox Code Playgroud) 有没有办法通过命令行打开背景选项卡?
例如(在 Windows 中):C:\Progra~1\Mozilla\Firefox\firefox.exe -new-tab http://www.yahoo.com
将始终打开该选项卡并使其成为焦点选项卡。我似乎找不到在后台打开该选项卡的方法。任何帮助将不胜感激。
我正在开发一个“动态快捷方式”应用程序,它创建指向注册表项而不是实际文件/可执行文件的特殊快捷方式文件。注册表项包含所需文件的路径。我想要运行一个守护进程,它监视链接到的文件,并在移动或重命名它们时更新它们的注册表项。重命名后我可以使用 System.IO.FileSystemWatcher 进行处理,但是处理移动文件的最佳方法是什么?
我知道这超出了 FSW 的基本功能(尽管是低级文件系统操作)。问题是,最好的方法是什么?
我读过的大多数帖子/文章都提出了感觉完全“hacky”的方法,这些方法基本上涉及寻找删除,然后在文件的新位置创建,并通过文件大小、元数据、文件之间的时间连接两者。删除/创建触发器、哈希等。这很可能是我必须采用的方法,在所有驱动器上设置 FSW。不过,我希望可能有更好的方法。
是否可以:
2.1. 监听 shell 并“听到”移动操作?
2.2 或者(甚至更激进)替换或添加一些东西到 shell 移动操作中,触发某种事件或执行注册表更新任务本身,从而消除对守护程序的需要?
我有一种感觉,每个人都会告诉我 1. 是唯一的课程,但我期待您的建议。(首选 VB.NET 中的答案,但如果需要,可以从 C# 进行翻译)。
我的目标是确定打印机的当前状态。我找到了以下代码。这是一个稍微修改的版本,用于修复内存泄漏和错误:
#include <Winspool.h>
int GetPrinterStatus( char* szPrnName )
{
HANDLE hHandle = 0; // Handle of the printer
DWORD dwStatus = 0; // Printer status we should receive
DWORD dwSize = 0; // Size of memory we should
// allocate for PRINTER_INFO_2
PRINTER_INFO_2* pPrnInfo2 = 0; // Structure specifies detailed
// printer information
DEVMODE DevMode = {0}; // Structure contains information
// about the device initialization
// and environment of a printer
PRINTER_DEFAULTS PrnDef = { 0, &DevMode, …Run Code Online (Sandbox Code Playgroud) 我最近观察到,我的文件夹预览处理程序未在 Windows 10 版本 1709 上实例化。这令人惊讶,因为该处理程序在从 Windows 7 到 Windows 10 版本 1607 运行的系统上都能完美运行。
预览处理程序以标准化方式在ProgID 下注册Directory:
HKEY_CLASSES_ROOT
Directory
shellex
{8895b1c6-b41f-4c1c-a562-0d564250836f}
(Default) = [REG_SZ] {1F176730-9812-47D8-8163-35D7C1CA0FBF}
Run Code Online (Sandbox Code Playgroud)
可以通过监视 Windows 资源管理器的注册表访问来跟踪工作系统和非工作系统之间的差异。当在 1607 系统上请求预览文件夹时,进程监视器会生成预期的输出:
另一方面,在 1709 系统上,该HKEY_CLASSES_ROOT\Directory键下根本没有注册表访问权限。这就是为什么我怀疑不同的行为(不幸的是)与我的处理程序代码没有任何关系,并且对文件夹的预览处理程序支持可能已在最近的 Windows 版本中删除。
我还使用ProgID Folder进行了测试,而不是Directory没有成功,并验证了我的预览处理程序通常会实例化,至少在文件上,通过在AllFileSystemObjects.
有人有在最新 Windows 版本上运行文件夹预览处理程序的经验吗?
似乎在 Windows 中调用 SHChangeNotify 不会调用对 QuickAccess 窗格中的项目(或在资源管理器左侧找到的任何自定义命名空间文件夹)的更新。似乎将左侧的树扩展到文件夹可以正常工作,右侧主视图中的任何内容也可以正常工作。
我们从 ac# WPF 应用程序调用 SHChangeNotify,尽管 SHChangeNotify 似乎在资源管理器中调用我们的 DLL 挂钩,对于正确视图中的任何内容都很好。这最终将调用一个命名管道,该管道将挂钩回我们的 C# 代码以调用文件或文件夹图标的更新。
这是我们从 c# 中调用的:
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern void SHChangeNotify(
int wEventId,
uint uFlags,
IntPtr dwItem1,
IntPtr dwItem2);
var ptr = Marshal.StringToHGlobalUni(fullPath);
SHChangeNotify((int)SHCNE.SHCNE_UPDATEITEM, (int)(SHCNF.SHCNF_PATHW | SHCNF.SHCNF_FLUSHNOWAIT), ptr, IntPtr.Zero);
Marshal.FreeHGlobal(ptr);
Run Code Online (Sandbox Code Playgroud)
我们可以假设所有常量和枚举都已正确定义。
请注意,灰色图标是默认图标。主窗口中的绿色图标是通过使用路径调用上面的函数来触发的C:\Users\Test User\Pocket Test。我认为这应该触发两个文件夹的刷新。
我也尝试过替换SHCNF_FLUSHNOWAIT为SHCNF_FLUSH. 我不知道如何继续这里。关于如何强制更新资源管理器左窗格中的文件夹有什么想法吗?
我想使用IFileOperation从 python 代码复制文件 -
在 Windows 10 上,Python 3.8 -
import ctypes
ctypes.windll.shell32.IFileOperation
Run Code Online (Sandbox Code Playgroud)
似乎不存在。
我怎样才能使用IFileOperation(不是已弃用的SHFileOperationAPI)ctypes?
windows-shell ×10
c++ ×4
winapi ×4
com ×3
c# ×2
windows ×2
background ×1
c ×1
command-line ×1
ctypes ×1
filesystems ×1
firefox ×1
icons ×1
mapi ×1
mfc ×1
printing ×1
python ×1
python-3.x ×1
shell ×1
vb.net ×1