当我使用ruby打印出windows 7 system32目录中的所有文件时,有些文件丢失了。 我使用这个简单的目录迭代:
Dir.foreach("C:\\Windows\\System32") do |fname| puts fname end
我特别寻找python27.dll,这是不打印,虽然它存在。 文件已存在? 似乎与dir迭代有相同的问题。 它为一个现有的文件返回false:
File.exists? "C:\\Windows\\System32\\python27.dll" #returns false
检查文件夹的另一个现有文件的工作原理:
File.exists? "C:\\Windows\\System32\\quartz.dll" #returns true
但是,如果我复制一个现有的文件或在system32中创build一个新的文件,这是行不通的
File.exists? "C:\\Windows\\System32\\quartz2.dll" #returns false
此外,将python27.dll复制到另一个目录并检查存在的工作:
File.exists? "C:\\Otherfolder\\python27.dll" #returns true
这个问题与字母大小写或path分隔符无关。 我查了一下 此外,我没有看到文件的用户权限的差异,工作,不…
我真的不知道,为什么发生这种情况…任何人都可以重现这个?
谢谢
[编辑]
花了一段时间,但我find了答案。
这是一个32/64位的问题。 对于ruby作为32位应用程序,“C:\ Windows \ System32”实际上是“C:\ Windows \ SysWOW64”。 正如64位的WinExplorer所显示的,python27.dll在System32中(只有64位进程看到了 – 很好,令人困惑),应该是在SysWOW64中,以便ruby能够看到。 安装32位版本的Python解决了我的问题(因为我不能更改ruby脚本,因为它是rubypython的一部分)。
在Windows 7(实际上是Vista)中,早期版本的Windows中只存在于纸上的许多安全策略现在实际上是由操作系统执行的。 例如,根据微软的文档,几十年来写C:\Windows\System32
几乎是非法的,但是如果你真的尝试过了,它仍然可以工作。 不再。 从Vista开始, C:\Windows\System32
就被禁止了。
但是,为了不打破现有(破碎)的应用程序,微软推出了文件系统虚拟化。 如果某个应用程序试图写入C:\Windows\System32
,它会被静默地重定向到C:\Users\%Username%\AppData\Local\VirtualStore\Windows\System32
。 因此,这个特定的应用程序会看到它在C:\Windows\System32
创建或更改的所有文件,但其他应用程序只能看到未更改的/空目录。
这不仅适用于C:\Windows\System32
,也适用于其他系统目录。 此外,它适用于注册表的系统部分,例如HKEY_LOCAL_MACHINE
。
这个虚拟化是每个应用程序。 也就是说,如果应用程序A试图创建或修改受保护目录中的文件,则Windows将拦截该调用并将其重定向到VirtualStore。 它也会记录这个重定向的地方。 现在,当相同的应用程序A试图再次查看时,Windows将使用记录的重定向,以便应用程序认为该文件是放置的位置,而事实上,该文件位于其他位置。
但是,如果不同的应用程序B查看该目录,则不会触发重定向,而只会看到一个原始系统目录。 这是一个重点:过去,不同的应用程序会通过覆盖系统目录中的对方文件来创建各种奇怪的错误。 即一个应用程序将其python27.dll
转储到C:\Windows\System32
和另一个应用程序将转储自己的,略有不同的python27.dll
不兼容的版本,覆盖第一个。
所以,你用一个应用程序来复制那里的DLL(可能是explorer.exe
),然后你使用不同的应用程序,即ruby.exe
来查看它。 但explorer.exe
并没有真正将其复制到system32
,它被重定向到VirtualStore。 当你使用explorer.exe
,重定向会被触发,你可以看到你认为放在哪里的文件,但是当你使用ruby.exe
,重定向不会被触发,而是会看到目录。
我敢打赌
File.exists? "C:/Users/#{ENV['Username']}/AppData/Local/VirtualStore/Windows/System32/python27.dll"
返回true
。
您确定这些文件在C:\\Windows\\System32\\
中可用吗?
我不知道从System32
夹中的这个问题,但我遇到了像Program Files
-folder一样的问题。
如果您尝试将某些系统文件夹中的数据保存起来并且您不是Admin,则Win7不会将其存储在该位置,而是存储在特定于用户的虚拟存储中。 当你看你的系统文件夹时,虚拟商店中的文件也显示在那里。 但路径是另一个。
您可以在c:\users\<username>\Appdata\local\Virtual Store\
查看您的虚拟商店(至少程序文件夹在那里)。
我有同样的问题,事实证明,使用超过260个符号的路径时,红宝石可以这样做:
Administrator@WIN-NUMKGBH6IIM ~ $ mkdir -p /cygdrive/c/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/ Administrator@WIN-NUMKGBH6IIM ~ $ /cygdrive/c/opscode/chef/embedded/bin/ruby <<'EOF' puts File.exists?("C:/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/") EOF true Administrator@WIN-NUMKGBH6IIM ~ $ /cygdrive/c/opscode/chef/embedded/bin/ruby <<'EOF' puts File.exists?("C:/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/") EOF false