2012-08-25 40 views
2

當我使用ruby打印出windows 7 system32目錄中的所有文件時,有些文件丟失。我用這個簡單的目錄迭代:System32中的Ruby Dir.foreach錯過文件/ File.exists?對現有文件返回false

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一個新的

File.exists? "C:\\Windows\\System32\\quartz2.dll" #returns false 

而且,在複印python27.dll到另一個目錄,並檢查是否存在工作:

File.exists? "C:\\Otherfolder\\python27.dll" #returns true 

該問題與字母大小寫或路徑分隔符無關。我檢查了。此外,我沒有看到用戶權限的文件的工作,不...

我真的不知道,爲什麼發生這種情況......任何人都可以重現這???

感謝

[編輯]

了一段時間,但我找到了答案。

這是一個32/64位的問題。對於ruby作爲32位應用程序,「C:\ Windows \ System32」實際上是「C:\ Windows \ SysWOW64」。正如64位WinExplorer所顯示的,python27.dll在System32中(只有64位進程看到了 - 很好,令人困惑),它應該在SysWOW64中,以便ruby能夠看到。安裝32位版本的Python解決了我的問題(因爲我無法更改ruby腳本,因爲它是rubypython的一部分)。

+0

我不認爲這是問題,但我更喜歡使用' /'而不是\或屏蔽\ \,即使我使用Windows。 '/'可以正常工作,並且\我遇到了問題。還有'File :: SEPARATOR',你可以用'File.join'建立路徑。 – knut

回答

2

您確定這些文件有C:\\Windows\\System32\\嗎?

我不知道System32-文件夾中存在這個問題,但我遇到了一些像Program Files-文件夾一樣的問題。

如果您嘗試在某些系統文件夾中保存數據並且您不是Admin,則Win7不會將其存儲在該位置,而是存儲在特定於用戶的虛擬存儲中。當您查看系統文件夾時,虛擬商店中的文件也會顯示在那裏。但路徑是另一個。

你可以在c:\users\<username>\Appdata\local\Virtual Store\的任何地方檢查你的虛擬商店(至少在那裏是程序文件夾)。

+0

感謝您的回答。寶貴的信息和很好的猜測。但實際的問題是32/64位問題。 – CodeSalad

3

在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查看該目錄,則不會觸發重定向,並且B只會看到一個原始系統目錄。這是重點:過去,不同的應用程序會通過在系統目錄中覆蓋對方的文件來創建各種奇怪的錯誤。即一個應用程序會將其python27.dll轉儲到C:\Windows\System32中,另一個應用程序會轉儲自己的,不同的不兼容版本python27.dll,覆蓋第一個應用程序。

所以,你用一個應用到那裏複製的DLL(可能explorer.exe),並使用一個不同的應用,即ruby.exe來看待它。但是explorer.exe didnt't 實際上複製到system32,它被重定向到VirtualStore。當您使用explorer.exe,重定向被觸發,你看到你認爲你把它放在文件的權利,但是當你使用ruby.exe,重定向確實被觸發,它看到的目錄,它實際上是。

打賭

File.exists? "C:/Users/#{ENV['Username']}/AppData/Local/VirtualStore/Windows/System32/python27.dll" 

回報true

+0

感謝您的回答。寶貴的信息和很好的猜測。但實際的問題是32/64位問題。 – CodeSalad

+1

@CodeSalad:是的,這基本上是一樣的事情,但爲了不同的目的。 –

0

我有同樣的問題,事實證明,紅寶石可以用比260個的符號路徑較長工作時,這樣的行爲:

[email protected] ~ 
    $ 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/ 

    [email protected] ~ 
    $ /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 

    [email protected] ~ 
    $ /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 
相關問題