2016-11-30 1 views
5

Zunächst einmal weiß ich, dass es viele Fragen gibt, die wie diese aussehen, aber ich konnte nicht wirklich eine Antwort auf mein Problem bekommen.Wie bekomme ich den Pfad einer Datei mit dem Namen der Datei [C#]

Also im Allgemeinen, ich führe ein Programm, das einen Weg zu einer Lösung einer anderen Visual Studio Projekt Lösungsdatei erhalten muss und ich habe nur den Namen der Datei selbst.

Zum Beispiel, läuft mein Programm im Hintergrund und es gibt ein visuelles Studio-Projekt, das gerade codiert wird, muss ich den Weg zur Lösung dieses Projekts finden. Das Projekt wurde noch nicht kompiliert, es ist ein neues Projekt, das gerade erstellt wurde. Zum Beispiel MyProject.sln ist die Datei und das Verzeichnis, das ich suche, ist C:\Users\MyUser\Documents\Visual Studio 2015\Projects\MyProject\MyProject.sln. Natürlich kann das Projekt irgendwo auf dem Computer sein, wie ein anderes Laufwerk oder nicht im Visual Studio Ordner.

Ich habe versucht, Methoden wie Path.GetDirectoryName(filename) verwendet, die einen leeren String zurückgibt, oder Path.GetFullPath(path), die einen falschen Weg zurückgibt (die von dem Programm, das für den Pfad sucht) oder Directory.GetDirectories(path,searchPattern) einige mit den Suchoption, und dann bekomme ich Berechtigungsfehler für SearchOption.AllDirectories auf vielen Dateien.

Ich bin wirklich hier verloren, ich hoffe jemand kann helfen!

+0

So, mögen Sie den Pfad zu dem Projekt finden, die in Visual Studio geöffnet ist ... Ich bin mir nicht sicher, ob Sie das schaffen können - nicht so einfach. – Sayse

+2

Wenn Sie den Namen haben, können Sie natürlich eine iterative Suche über die verfügbaren Laufwerke durchführen, aber das kann je nach Laufwerk sehr lange dauern. alternativ könnten Sie sehen, ob Sie den Prozess abfragen und herausfinden können, welche Dateien er geöffnet hat – BugFinder

+0

@BugFinder was bedeutet es, den Prozess zu interogieren? –

Antwort

1

Ich denke nicht, dass Sie in der Lage sein werden, den Projektpfad in Visual Studio leicht zu bekommen.

Es wäre viel einfacher, wenn Sie Ihr eigenes Programm derjenige ist Visual Studio und das Projekt zu öffnen - was natürlich einige Benutzer Zusammenarbeit

ich es nicht versuchte, mich erfordern würde, aber sie müssen verwenden der devenv Befehl in Ihrem eigenen Programm

Devenv /edit [file1[ file2]] 
0

Verwenden

var ProjectLocation = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())); 
    var SlnLocation = (ProjectLocation + "\\" + "SolutionName.sln"); 

dies wird Ihnen das vollständige Verzeichnis geben.

+1

dieser gibt mir den Pfad meines Programms Standort. Ich brauche den Pfad eines anderen visuellen Studio-Programms, das codiert wird –

+0

Sie könnten das Verzeichnis immer nur hart codieren ... aber den Namen des Projekts als Variable in der Zeichenfolge verwenden. –

+0

Ich kann das Verzeichnis nicht fest codieren, da das Projekt überall im Computer erstellt werden kann. Ich muss seinen Weg finden, wenn es erstellt wird. –

0

Hier ist der Code, der nach dem Dateinamen der Datei im gesamten Dateisystem sucht, ich hoffe, das wird Ihnen helfen.

static void Main(string[] args) 
    { 
     Console.WriteLine("Enter file name..."); 
     string fileName = Console.ReadLine(); 
     var result = FindFile(fileName); 
     foreach (var files in result) 
     { 
      foreach (var file in files) 
      { 
       Console.WriteLine(file); 
      } 
     } 
    } 

    public static List<string[]> FindFile(string fileName) 
    { 
     string[] drives = Environment.GetLogicalDrives(); 
     List<string[]> findedFiles = new List<string[]>(); 
     foreach (string dr in drives) 
     { 
      Console.WriteLine($"Start looking in {dr}"); 
      System.IO.DriveInfo di = new System.IO.DriveInfo(dr); 
      if (!di.IsReady) 
      { 
       Console.WriteLine("The drive {0} could not be read", di.Name); 
       continue; 
      } 
      DirectoryInfo rootDir = di.RootDirectory; 
      var findedFiletmp = Directory.GetFiles(rootDir.Name, fileName, SearchOption.TopDirectoryOnly); 
      if (findedFiletmp.Length > 0) 
      { 
       findedFiles.Add(findedFiletmp); 
       Console.WriteLine("Finded file.Continue search?(Y/N)"); 
       string answer = Console.ReadLine(); 
       if (answer.ToLower().Equals("n")) 
       { 
        break; 
       } 
      } 
      var subDirectories = Directory.GetDirectories(rootDir.Name); 
      bool breaked = false; 
      foreach (var subDirectory in subDirectories) 
      { 
       try 
       { 
        var findedFiletmp1 = Directory.GetFiles(subDirectory, fileName, SearchOption.AllDirectories); 
        if (findedFiletmp1.Length > 0) 
        { 
         findedFiles.Add(findedFiletmp1); 
         Console.WriteLine("Finded file.Continue search?(Y/N)"); 
         string answer = Console.ReadLine(); 
         if (answer.ToLower().Equals("n")) 
         { 
          breaked = true; 
          break; 
         } 
        } 
       } 
       catch (Exception exc) 
       { 
        Console.WriteLine(exc.Message); 
       } 
      } 
      Console.WriteLine($"Finished looking in {dr}"); 
      if (breaked) 
       break; 
     } 
     return findedFiles; 
    } 
+0

Fehler verwenden, es scheint nur die ersten Verzeichnisse unter den Laufwerken warf. Wie kann ich tiefer gehen, ohne die nicht autorisierte Ausnahme zu bekommen? –

+0

@RonBitterman iteriert die ersten Verzeichnisdateien und wechselt in andere Verzeichnisse, wenn Sie über Zugriffsrechte für diese Ordner verfügen. Sie können nicht ohne Rechte auf sie zugreifen. –

0

Hier ist eine Lösung für Sie. Es analysiert alle offenen Prozesse, um alle in Visual Studio geöffneten zu finden (auch nicht laufende Dateien erstellen immer noch einen vshost-Prozess). Dann prüft es den Namen des Prozessmoduls anhand Ihres angegebenen Namens und gibt schließlich den Pfad zur Lösungsdatei zurück.Das Beispiel in button1_click zeigt, wie die tatsächliche Lösung Dateinamen abzurufen (nicht sicher, ob es überhaupt aus dem Verzeichnisnamen sowieso unterscheiden würde):

public string GetVSProgramPath(string filename) 
    { 
     Process[] plist = Process.GetProcesses(); 

     foreach (Process theprocess in plist) 
     { 
      try 
      { 
       ProcessModule pm = theprocess.MainModule; 
       if (theprocess.MainModule.ModuleName.Contains("vshost") && theprocess.MainModule.ModuleName.ToLower().Contains(filename.ToLower())) 
       { 
        string path = theprocess.MainModule.FileName; 
        int loc = path.IndexOf(@"\Projects\"); 
        return path.Substring(0, path.IndexOf(@"\", loc + 10));       
       } 
      } 
      catch (Exception ex) 
      { 
      } 
     } 
     return string.Empty; 
    } 

Ein Beispiel für die Nutzung:

private void button1_Click(object sender, EventArgs e) 
    { 
     string path = GetVSProgramPath("MyProject"); 
     string solutionFile = System.IO.Directory.GetFiles(path, "*.sln")[0]; 

    } 

Ich weiß, die Suche nicht optimiert ist, aber ich werde diesen Teil Ihnen überlassen;)

+0

Dadurch erhalten Sie den Projektpfad, nicht den Lösungsweg. Und es wird wahrscheinlich nicht funktionieren, wenn "Enable the Visual Studio hosting process" nicht in den Projekteigenschaften –

0

mit der code von @BugFinder vorgeschlagen, dass Sie etwas tun können:

static void Main(string[] args) 
{ 
    try 
    { 
     foreach (var proc in Process.GetProcessesByName("devenv")) 
     { 
      var files = Win32Processes.GetFilesLockedBy(proc); 
      Regex rgxDbFile = new Regex("\\.opendb$", RegexOptions.IgnoreCase); 
      foreach (var item in files.Where(f => rgxDbFile.IsMatch(f))) 
      { 
       Console.WriteLine(item); 
      } 
     } 
     Console.ReadKey(true); 
    } 
    catch (Exception ex) 
    { 
     ex.ToString(); 
    } 
} 

Wir filtern die zurückgegebenen Werte mit der Regex \\.opendb$ weil VS eine Menge von Dateien und derjenige, der die geöffnete Lösung endet mit opendb Referenz öffnet:

enter image description here

dieser Weg gegeben wird es trivial sein zu erkennen, der Name .sln.

Hinweis: wenn VS als Administrator ausgeführt wird, auch Ihr Prozess müssen laufen mit, dass die Berechtigungen ...

+0

im get "System.AccessViolationException" für diese Zeile gekennzeichnet ist "var strObjectTypeName = Marshal.PtrToStringUni (ipTemp, objObjectType.Name.Length> > 1); 'und ich finde keine Antwort in diesem Beitrag, irgendwelche Vorschläge? –

+0

@RonBitterman Was ist die vollständige Nachricht der Ausnahme? Laufen Sie x64? –

+0

Ja, ich benutze x64. die vollständige Ausnahme: Versuch, geschützten Speicher zu lesen oder zu schreiben. Dies ist oft ein Hinweis darauf, dass anderer Speicher beschädigt ist. –

Verwandte Themen