自从我开始使用 Windows 7 以来,这个问题一直困扰着我。我不时会在杂项论坛上看到类似的问题,但我从未看到过答案。以下两种情况几乎总是会重现此问题:
探索者之路
- 使用资源管理器,导航到包含至少一个 exe 文件的目录
- 立即转到上一级目录
- 删除刚刚导航到的目录
- 收益文件夹访问被拒绝对话说明您需要获得权限才能执行此操作 您需要获得管理员的权限才能更改此文件夹,使用按钮再试一次和取消
- 打再试一次永远不会立即起作用。等待一分钟左右,然后再次单击它才会起作用
注意:如果在步骤 2 中等待一分钟或更长时间再上移一个目录,则不会出现该问题,并且可以删除该文件夹
Visual Studio 方式
- 建立一个项目并生成一个 exe 文件
- 运行可执行文件然后关闭它
- 立即重新构建项目(例如,通过更改源文件中的单个字符)
- 收益致命错误 LNK1168:无法打开 /path/to/the.exe 进行写入
注意:如果在步骤2中等待一分钟或更长时间再构建,则不会出现问题。
一些规格
- 在 Windows 7 32 位和 64 位上均会发生这种情况,使用 VS2008/2010/2011
- 发生在 3 台不同的机器上
- 我没有任何类型的病毒扫描程序
- 我确实禁用了许多服务,但这些服务并没有妨碍 Windows 正常运行,UAC 也已被禁用
- 发生在任何类型的光盘上
- 我总是使用属于管理员组的用户帐户
显然,这两种情况非常相似,而且极易重现。所以我想一定是某个进程出于某种原因打开了文件,然后稍后再次释放它。但是,使用 sysinternals
handle -a
有问题的 exe 文件绝不出现。(这是使用句柄的正确方法,对吧?)因此,当 explorer/VS 报告无法访问该文件时,handle.exe 却说它没有在任何地方使用。这让我很困惑,所以我想知道是否有人能想出一个解决方案:为什么会发生这种情况,以及如何解决它?
更新回答提出的问题:
- 我无法在安全模式下重现问题
- 安装了一堆 shell 扩展。从 SellExView 来看,以下是所有机器都通用的非微软扩展:NitroPDF、WinRAR、TortoiseGit、TortoiseSvn、NVidia。我认为 Tortoise 扩展最可疑,尽管两者的“状态缓存”选项都设置为“仅针对一个文件夹的状态缓存,无递归覆盖”,即没有 TortoiseCache.exe 在运行。
- 对于 explorer 问题,ProcessExplorer 不显示可执行文件。它确实显示了可执行文件的目录,但即使删除后仍继续显示,所以这似乎并不真正相关
- 对于 VS 问题,即使目标目录上没有打开资源管理器窗口,VS 也会发生这种情况。同样,ProcessExplorer 不会显示可执行文件,也不会显示可执行文件所在的目录。请注意,在 VS 的这种“模式”下,问题仅在运行可执行文件时发生。如果不运行它,我可以一次又一次地构建它而不会出现问题。
- 在“对战模式”中和在可执行文件的目录上打开一个资源管理器窗口(仅使用 C# exe 进行测试),情况变得更加奇怪:我无法再次构建,因为 VS 抱怨该 exe 正在被另一个进程使用。但是,如果我从打开的资源管理器窗口中删除该 exe,则此方法有效,因此构建成功。同样,ProcessExplorer 中没有任何引用。这似乎与我对 handle.exe 的发现相符(PE 和 handle 不是在内部使用相同的 API 吗?)
更新 2 这不可能只是 explorer:杀死 explorer.exe 之后,VS 问题仍然存在。
更新 3 按照 Asher 的建议使用 Process Monitor 可以发现一些有趣的事实:对于 explorer 模式,打开目录时有 10 次 IRP_MJ_CREATE 调用。但是只有 9 次 IRP_MJ_CLEANUP 调用。所有这些调用都来自 shell32.dll 内部,因此肯定是不是第三方安装问题。很明显,缺少 IRP_MJ_CLEANUP 导致了问题:打开目录后恰好 1 分钟,系统进程本身发出 IRP_MJ_CLEANUP 调用,文件被释放并被删除。
但是,我还是不明白为什么会发生这种情况。这是我做的一些更改引发的浏览器错误吗?
解决方案!查看我已禁用的服务,我注意到应用经验我说,处理应用程序的应用程序兼容性缓存请求推出后听起来很熟悉。事实上,启动服务后,我无法再重现任何问题,ProcMon 的输出也不同且更短。但有趣的是,因为再次停止服务后,一切仍然正常,procmon 的输出仍然更短。
我在两台机器上尝试过这个,所有第三方软件都运行正常,一切正常。
我不确定这是否是一个真正的错误(有人可能会说“禁用服务你期望什么”),但仅通过启动服务然后再次停止它就可以解决问题,这并不正常。
任何能够对此提供更深入见解的人都将获得赏金,此外还要感谢@Asher 向我指出 ProcMon,最终让我找到了正确的方向。
答案1
我认为您看到的问题与 Windows 资源管理器创建的 thumbs.db 有关。尝试禁用它,然后重新启动,看看问题是否重现。
要禁用 thumbs.db,请打开组策略编辑器 (gpedit.msc),转到用户配置 - 控制面板 > 管理模板 - 文件夹选项 > Windows 组件 - Viev 选项卡 > Windows 资源管理器。找到“关闭隐藏 thumbs.db 文件中缩略图的缓存”并启用它不缓存缩略图。
如果它不起作用,我会尝试使用 Sysinternals Process Monitor 来调查它。当您被拒绝访问时,使用它来观察谁在访问该文件夹。看看它是否实际上是访问被拒绝或共享冲突,这意味着有人持有该文件。
答案2
答案3
文件或目录可以从内核模式打开,然后
handle -a
不会显示它,而 ProcMon 将显示来自/到系统进程的 IRP 请求。
Windows 内核的一部分被映射到所有进程,另一部分则运行在单独的进程中。后者被称为 Windows Executive。
因此,这是由 Windows 执行进程中从内核模式打开的文件或目录引起的。
答案4
可能是 Explorer 正在从 exe 读取图标和元数据。