2010-07-15 22 views
1

I en utilisant C# .NET, vs 2008, .net 3.5questions au sujet des fichiers ou des dossiers utilisés: obtenir le nom d'un autre processus qui utilisent le fichier ou le dossier

Pour moi, est difficile, mais j'ai besoin exemple de code dans C# pour cela:

  1. Vérifiez si un fichier ou un dossier est en cours d'utilisation

  2. Si fichier ou un dossier est en cours d'utilisation, le nom du processus qui l'utilisent

Par exemple, dans mon numéro. J'essaye de supprimer le fichier, et j'obtiens "Le processus ne peut pas accéder au fichier 'XYZ' parce qu'il est utilisé par un autre processus." Exception.

File.Delete(infoFichero.Ruta);

Je veux vérifier si un fichier est utilisé, et le nom du processus qui l'utilisent.

J'ai besoin d'un exemple de code, code source, s'il vous plaît. Je ne veux pas utiliser C++, je ne sais pas c, C++, code non managé, ou WinApi. Je veux utiliser uniquement du code C# (code managé .net).

J'ai lu plusieurs références, mais pas obtenir du code source exemple,

Comment vérifier si un fichier est utilisé?

Emulate waiting on File.Open in C# when file is locked

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/9dabc172-237a-42db-850e-ada08885a5d5

How to check if a file is in use?

Easiest way to read text file which is locked by another application

Using C# is it possible to test if a lock is held on a file

EDIT: De Yan Jun - MSFT

string path = "D:\\temp2.xlsx"; 
      foreach (Process c in Process.GetProcesses()) { 

       if (c.MainWindowTitle.Contains(Path.GetFileName(path))){ 
        MessageBox.Show(c.ProcessName); 
        return; 
       } 
      } 

      try{ 
       FileInfo f = new FileInfo(path); 

       f.Delete(); 
      } 
      catch (Exception ex){ 

       MessageBox.Show(ex.Message); 
      } 

... Mais il est difficile d'obtenir une solution pour tous les problèmes de 100%.

  1. Problème si c.MainWindowTitle == null ou ne contient pas de nom de fichier.

  2. problème pour le dossier partagé dans une autre machine, PC, serveur, ... comme:

File.Delete (@ \ desiis \ Temporal \ projet \ script.targets);

un exemple de code, je demande de l'aide gourous, MVP, n'importe qui.

MISE À JOUR: le même problème pour un dossier

+0

Si 3 personnes vont voter en bas ceci devrait au moins dire pourquoi elles le font. –

Répondre

3

Il ne va pas être un moyen de trouver le processus qui a le fichier ouvert sans entrer dans le winapi, je ne pense pas.Et en ce qui concerne la vérification de son utilisation, la seule chose que vous pouvez vraiment faire, comme les questions SO que vous avez liées à l'état, est d'enrouler les tentatives d'accès au fichier dans un bloc try/catch.

Le code pour trouver quel fichier a ouvert est susceptible d'être moche, mais il peut y avoir une API là-bas qui enveloppe bien. Il existe des utilitaires tiers qui vous le diront (Unlocker étant l'exemple le plus connu). Vous pouvez également utiliser ProcessExplorer pour rechercher des handles de fichiers ouverts par le nom de fichier. Cela ne vous aide pas vraiment. La réponse courte de ce que j'essaie d'obtenir ici est que vous avez la réponse pour la première partie de votre question dans les questions SO que vous avez déjà liées, et la deuxième partie nécessiterait probablement des appels WIN32, que vous voulez éviter, mais vous allez probablement devoir vous salir les mains dans Win32 ... Vous voulez toujours de l'aide?

EDIT: Vous pouvez utiliser l'utilitaire sysinternals Handle. Vous devriez obtenir la sortie de cette commande et l'analyser vous-même. Vous pouvez lire le processus de la production comme celui-ci

string result = proc.StandardOutput.ReadToEnd(); 

exécuté Le problème avec ceci est que vous allez obtenir un accord de licence pop-up la première fois que vous exécutez l'utilitaire de poignée. Sans parler de toutes les questions de licence si c'est quelque chose que vous espérez déployer ...

Si vous êtes toujours intéressé, je peux vous montrer comment vous y prendre.

EDIT: Voici un programme exécutable qui trouvera le nom exe et le pid de tout programme ayant un handle ouvert dans un fichier. J'ai ajouté des commentaires, mais je peux élaborer plus avant si nécessaire. J'utilise ici les expressions rationnelles pour analyser la sortie car c'est ce qui est le plus logique compte tenu de la tâche à accomplir.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ProcessStartInfo si = new ProcessStartInfo(); 
      si.FileName = "handle.exe";  //name of the handle program from sysinternals 
              //assumes that its in the exe directory or in your path 
              //environment variable 

      //the following three lines are required to be able to read the output (StandardOutput) 
      //and hide the exe window. 
      si.RedirectStandardOutput = true; 
      si.WindowStyle = ProcessWindowStyle.Hidden; 
      si.UseShellExecute = false; 

      si.Arguments = "test.xlsx";  //this is the file you're trying to access that is locked 

      //these 4 lines create a process object, start it, then read the output to 
      //a new string variable "s" 
      Process p = new Process(); 
      p.StartInfo = si; 
      p.Start(); 
      string s = p.StandardOutput.ReadToEnd(); 

      //this will use regular expressions to search the output for process name 
      //and print it out to the console window 
      string regex = @"^\w*\.EXE"; 
      MatchCollection matches = Regex.Matches(s, regex, RegexOptions.Multiline); 
      foreach (var match in matches) 
      { 
       Console.WriteLine(match); 
      } 

      //this will use regex to search the output for the process id (pid) 
      //and print it to the console window. 
      regex = @"pid: (?<pid>[0-9]*)"; 
      matches = Regex.Matches(s, regex, RegexOptions.Multiline); 
      foreach (var obj in matches) 
      { 
       Match match = (Match)obj; //i have to cast to a Match object 
              //to be able to get the named group out 
       Console.WriteLine(match.Groups["pid"].Value.ToString()); 
      } 

      Console.Read(); 
     } 
    } 
} 
+0

Tim Coker, je suis toujours intéressé, si vous pouvez me montrer comment vous allez à ce sujet. Merci – Kiquenet

1

Il n'y a pas de façon purement gérée de le faire. Vous devez utiliser des API de bas niveau via P/invoke ou similaire.

Il y a une bonne information ici sur un moyen de le faire, mais c'est du code C++. Vous devriez faire le portage vous-même.

http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

Remarque il y a des problèmes complexes avec celui-ci, à savoir les questions autour du noyau par rapport à la mémoire userspace. Ce n'est pas un problème simple que vous essayez de résoudre.