Windows 7 访问拒绝可执行文件.. 什么?

sti*_*ijn 14 windows-7 visual-studio

自从我开始使用 Windows 7 以来,这个问题一直困扰着我。有时我会在其他论坛上看到类似的问题,但我从来没有看到答案。以下是几乎总是会重现它的两种场景:

探索者之路

  1. 使用资源管理器,导航到至少包含一个 exe 文件的目录
  2. 立即上一级目录
  3. 删除刚刚导航到的目录
  4. 产生文件夹访问被拒绝对话框,说明您需要执行此操作的权限您需要管理员的权限才能更改此文件夹,按钮再次尝试取消
  5. 点击再次尝试永远不会立即起作用。等待一分钟左右,然后再次单击它确实有效

注意:如果在步骤 2 中等待一分钟或更长时间再上一个目录,则不会出现问题,可以删除该文件夹

Visual Studio 方式

  1. 构建一个生成 exe 文件的项目
  2. 运行可执行文件然后关闭它
  3. 立即再次构建项目(例如,通过更改源文件中的单个字符)
  4. 产生致命错误 LNK1168:无法打开 /path/to/the.exe 进行写入

注意:如果在步骤 2 中等待一分钟或更长时间再重新构建,则不会出现问题。

一些规格

  • 在 VS2008/2010/2011 的 Windows 7 32 位和 64 位上都发生
  • 发生在 3 台不同的机器上
  • 我没有任何类型的病毒扫描程序
  • 我确实禁用了一堆服务,但没有什么可以阻止 Windows 正常运行,UAC 也被禁用
  • 发生在任何类型的光盘上
  • 我总是使用管理员组中的用户帐户

显然,这两种情况都非常相似,并且具有极强的可重现性。所以我认为某些进程出于某种原因必须打开文件,然后再释放它。但是,使用 sysinternals

handle -a
Run Code Online (Sandbox Code Playgroud)

有问题的 exe 文件永远不会出现。(这是使用句柄的正确方法,对吗?)因此,当资源管理器/VS 报告他们无法访问该文件时,handle.exe 表示它没有在任何地方使用。这让我很无能为力,所以我想知道是否有人可以提出解决方案:为什么会发生这种情况,以及如何解决?

针对提出的问题进行更新

  • 我无法在安全模式下重现该问题
  • 安装了一堆shell扩展。从 SellExView,这里是所有机器通用的非微软的:NitroPDF、WinRAR、TortoiseGit、TortoiseSvn、NVidia。我会发现 Tortoise 最可疑,尽管“状态缓存”选项都设置为“状态缓存仅用于一个文件夹,没有递归覆盖”,即没有运行 TortoiseCache.exe。
  • 对于资源管理器问题,ProcessExplorer 不显示可执行文件。它确实显示了可执行文件的目录,但即使在删除后仍继续显示它,因此似乎没有真正相关
  • 对于 VS 问题,即使在目标目录上没有打开资源管理器窗口,VS 也会发生这种情况。同样,ProcessExplorer 不显示可执行文件,也不显示可执行文件所在的目录。请注意,在 VS 的这种“模式”中,问题仅在运行可执行文件时出现。如果不运行它,我可以一次又一次地构建它而不会出现问题。
  • 在“VS 模式”在可执行文件目录上打开的资源管理器窗口(仅使用 C# exe 测试)下,它变得更奇怪:我无法再次构建,因为 VS 抱怨 exe 正在被另一个进程使用。但是,如果我从打开的资源管理器窗口中删除 exe,这会起作用,因此构建成功。同样,ProcessExplorer 中没有任何引用。这似乎与我的发现与 handle.exe 相符(无论如何,PE 和句柄在内部不使用相同的 API?)

Update 2 不能只是explorer:杀掉explorer.exe后,VS问题依然存在。

更新 3 按照 Asher 的建议使用 Process Monitor 揭示了有趣的事实:对于资源管理器模式,打开目录时有 10 次调用 IRP_MJ_CREATE。然而,只有 9 次调用 IRP_MJ_CLEANUP。所有这些调用都来自 shell32.dll,所以这绝对不是3rd 方安装问题。并且显然是缺少 IRP_MJ_CLEANUP 导致了问题:在打开目录后恰好 1 分钟,系统进程本身发出 IRP_MJ_CLEANUP 调用,文件被释放,并被删除。

但是,我仍然无法弄清楚为什么会发生这种情况。这是我所做的一些更改触发的资源管理器错误吗?

解决方案!查看我禁用的服务,我注意到Application Experience的描述说,我引用了Processes application compatible cache requests for applications as they are launch。听起来很熟悉。事实上,在启动服务后,我再也无法重现任何问题,而且 ProcMon 的输出不同且更短。不过很有趣,因为再次停止服务后,一切都还好,procmon 的输出仍然较短。

我在两台机器上尝试了这个,所有 3rd 方的东西都在愉快地运行,一切都还好。

我不确定这是否是一个真正的错误(人们可能会说“您对禁用服务有什么期望”),但是仅仅通过启动服务然后再次停止服务就可以解决问题并不完全正常。


任何能对此提供更深入见解的人都会获得赏金,否则@Asher 将我指向 ProcMon,这最终将我引向了正确的方向。

Ash*_*her 7

我认为您看到的问题与 Windows 资源管理器创建的 thumbs.db 相关。尝试禁用此功能,重新启动并查看问题是否重现。

要禁用 thumbs.db 打开组策略编辑器 (gpedit.msc),请转到用户配置 - 控制面板 > 管理模板 - 文件夹选项 > Windows 组件 - Viev 选项卡 > Windows 资源管理器。找到“关闭隐藏的thumbs.db文件中的缩略图缓存”并启用它不缓存缩略图。

如果它不起作用,我会尝试使用 Sysinternals Process Monitor 对其进行调查。当您访问被拒绝时,使用它来查看谁正在访问该文件夹。查看它是否实际上是访问被拒绝或共享冲突,这意味着有人持有该文件。

  • @kinokijuf 我刚刚注意到你一直在搞乱阿瑟的回答。我不知道你为什么要这样做,但它没有意义:首先你用粗体说没有thumbs.db。然后你编辑 Asher 的答案,所以他说如何禁用 thums.db 的部分,使其无法使用(“不要缓存缩略图”适用于 XP)。请不要做这样的事情。 (3认同)
  • 赞成:虽然我没有不缓存缩略图选项,但使用 ProcMon 终于找到了我,因为它提供了问题的证据,不像 ProcessExplorer 或句柄:在打开目录或运行 exe 后正好 1 分钟,有一个 IRP_MJ_CLEANUP似乎释放文件的系统进程的操作:在该事件之后,我可以再次删除该目录。如果我能从 ProcMon 提供的内容中理解的话,我将进一步调查这一点。 (2认同)