2012-08-25 2 views
2

Lorsque j'imprime tous les fichiers dans le répertoire Windows 7 system32 à l'aide de ruby, certains fichiers sont manquants. J'utilise cette simple itération de répertoire:Ruby Dir.foreach dans System32 manque fichiers/File.exists? renvoie false pour les fichiers existants

Dir.foreach("C:\\Windows\\System32") do |fname| 
    puts fname 
end 

Je cherche spécifiquement pour python27.dll, qui n'est pas imprimé, mais il existe. Le fichier existe? semble avoir le même problème que l'itération dir. elle retourne false pour un fichier existant:

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

Vérification d'un autre fichier existant du dossier fonctionne:

File.exists? "C:\\Windows\\System32\\quartz.dll" #returns true 

Mais cela ne fonctionne pas si je dupliquer un fichier existant ou en créer un nouveau en system32

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

En outre, la copie python27.dll dans un autre répertoire et de vérifier l'existence fonctionne:

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

Le problème n'a rien à voir avec la casse ou le délimiteur de chemin. J'ai vérifié ça. En outre, je ne vois pas de différences dans les droits d'utilisateur pour les fichiers qui fonctionnent et qui ne le font pas ...

Je n'ai vraiment aucune idée, pourquoi cela arrive ... quelqu'un peut-il reproduire cela ???

grâce

[modifier]

pris un certain temps, mais je trouve la réponse.

Il s'agissait d'un problème 32/64 bits. pour ruby ​​en tant qu'application 32 bits, "C: \ Windows \ System32" est en fait "C: \ Windows \ SysWOW64". Comme le WinExplorer 64 bits l'a montré, python27.dll était dans System32 (que seuls les processus 64bit voient - bien, confus), alors qu'il aurait dû être dans SysWOW64 pour voir ruby. L'installation de la version 32 bits de Python a résolu le problème pour moi (comme je ne pouvais pas changer le script ruby, car il faisait partie de rubypython).

+0

Je ne pense pas que c'est le problème, mais je préfère utiliser '/'à la place \ ou masqué \\, même quand je travaille avec Windows. '/' fonctionne bien et avec \ j'ai des problèmes. Il y a aussi 'File :: SEPARATOR' et vous pouvez construire des chemins avec' File.join'. – knut

Répondre

2

Êtes-vous sûr que les fichiers sont disponibles dans C:\\Windows\\System32\\?

Je ne connais pas ce problème dans le dossier System32, mais j'ai eu quelques problèmes comme le vôtre avec le dossier Program Files. Si vous essayez d'enregistrer des données dans certains dossiers système et que vous n'êtes pas administrateur, Win7 ne les stocke pas à cet emplacement, mais dans un magasin virtuel spécifique à l'utilisateur. Lorsque vous regardez votre dossier système, les fichiers du magasin virtuel y sont également affichés. Mais le chemin en est un autre.

Vous pouvez vérifier votre magasin virtuel n'importe où dans c:\users\<username>\Appdata\local\Virtual Store\ (au moins le dossier Programme est là).

+0

Merci pour la réponse. Informations précieuses et une bonne estimation. Le problème réel était un problème 32/64-bit cependant. – CodeSalad

3

Dans Windows 7 (Vista, en fait), de nombreuses stratégies de sécurité qui n'existaient que sur papier dans les versions antérieures de Windows sont maintenant appliquées par le système d'exploitation. Par exemple, selon la documentation de Microsoft, il est pratiquement illégal d'écrire à C:\Windows\System32 depuis des décennies maintenant, mais si vous l'avez réellement essayé, cela a quand même fonctionné. Plus maintenant. À partir de Vista, C:\Windows\System32 est interdit.Toutefois, afin de ne pas casser les applications (cassées) existantes, Microsoft a introduit la virtualisation du système de fichiers. Si une application essaie d'écrire à C:\Windows\System32, elle est redirigée silencieusement vers C:\Users\%Username%\AppData\Local\VirtualStore\Windows\System32. Ainsi, cette application spécifique voit tous les fichiers qu'elle a créés ou modifiés dans C:\Windows\System32, mais autres applications ne voient que le répertoire inchangé/vide.

Cela ne s'applique pas seulement à C:\Windows\System32 mais également à d'autres répertoires système. En outre, il s'applique aux parties du système du registre, par exemple HKEY_LOCAL_MACHINE.

Cette virtualisation est par application. C'est à dire. Si l'application A tente de créer ou de modifier un fichier dans un répertoire protégé, Windows intercepte cet appel et le redirige vers VirtualStore. Il enregistrera également cette redirection quelque part. Maintenant, quand cette même application A essaie de regarder là encore, Windows utilisera la redirection enregistrée, de sorte que l'application pense le fichier est où il l'a mis, alors qu'en fait, il est ailleurs.

Cependant, si un différent application B regarde ce répertoire, alors la redirection n'est pas déclenchée et B voit juste un répertoire système vierge. C'est tout le problème: dans le passé, différentes applications créaient toutes sortes de bogues bizarres en écrasant les fichiers des uns et des autres dans les répertoires du système. C'est à dire. une application viderait son python27.dll en C:\Windows\System32 et une autre application viderait sa propre version, légèrement différente de python27.dll, écrasant la première.

Donc, vous avez utilisé une application pour copier la DLL là (probablement explorer.exe) et que vous utilisez une application différente , à savoir ruby.exe à regarder. Mais explorer.exe n'a pas effectivement le copier dans system32, il a été redirigé vers le VirtualStore. Lorsque vous utilisez explorer.exe, la redirection est déclenchée et vous voyez le fichier là où pensez vous l'avez mis, mais lorsque vous utilisez ruby.exe, la redirection pas se déclenche et il voit le répertoire tel qu'il est réellement.

Je parie que

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

retours true.

+0

Merci pour la réponse. Informations précieuses et une bonne estimation. Le problème réel était un problème 32/64-bit cependant. – CodeSalad

+1

@CodeSalad: Oui, c'est essentiellement la même chose, mais dans un but différent. –

0

J'ai eu même problème, il est avéré que Ruby peut se comporter de cette façon lorsque vous travaillez avec des chemins de plus de 260 symboles:

[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 
Questions connexes