2013-11-14 1 views
5

Ich schreibe ein. Net WinForms auf und ständig zwischen DEBUG und RELEASE Konfigurationen wechseln und habe ein paar Dateien, die ich brauche, um beide Konfiguration zu können.Environment.CurrentDirectory vs System.IO.Directory.GetCurrentDirectory

Was ich dachte, war zu tun, um die Dateien in einem gemeinsamen Verzeichnis im BIN-Verzeichnis zu setzen, so dass es würde wie folgt aussehen:

MyProject/Bin/CommonFiles 
MyProject/Bin/Debug 
MyProject/Bin/Release 

Und ich dachte über die Dateien zugreifen etwas entlang der Linien mit von: da

System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory).FullName 

ist meine Frage, ob dies von dem, was ich gelesen habe, ist gefährlich, System.IO.Directory.GetCurrentDirectory aufgrund der Benutzer ändern könnte ein neues aktuelles Verzeichnis in, sagen wir, eine geöffnete Datei Dialogfenster auswählen.

Soll ich eher etwas entlang der Linien von verwenden:

System.IO.Directory.GetParent(Environment.CurrentDirectory).FullName 

OR gibt es einen noch besseren Weg zum /Bin Ordner zu bekommen, so kann ich von dort oder einen allgemein akzeptierten Art und Weise/Ort bewegen zu Speichern von Dateien, die das Programm normalerweise erreichen muss, und Möglichkeit, diese leichter zu referenzieren (vielleicht etwas, das mit jeder Art von App und nicht nur mit WinForms funktioniert)?

+0

Das bin-Verzeichnis ist Detail eine Implementierung des VS Build-System verwendet haben sollte . Da es unwahrscheinlich ist, dass Sie Ihr Projekt mit Quellcode an den Kunden versenden und Sie keine Dateien in c: \ program files \ bin speichern können, ist dies keine gute Vorgehensweise. Verwenden Sie% appdata% für beschreibbare Dateien, Ihr EXE-Verzeichnis oder% programdata% für schreibgeschützte Dateien. –

+0

Danke @HansPassant ... Wie ich Christian unten gesagt habe, bin ich etwas zögerlich, sie ständig in den AppData-Ordner auf dem Computer jedes Benutzers zu kopieren, da viele Benutzer dieses Programm nur einmal verwenden müssen und es auf einem freigegebenen Laufwerk in meiner Organisation ist an diesem Punkt ... Irgendwelche Gedanken dazu? –

Antwort

3

Obwohl die meisten der Antworten scheinen tat tatsächlich zu arbeiten, the solution offered by Joe above nach einer ziemlich wenig Zwicken, erwies sich als die beste Lösung für meine Situation.


Zum einen der endgültigen Lösung, die ich mit gegangen:

  • Erstellt ein Common Files Verzeichnis (In meinem Fall auf dem gleichen Niveau wie mein Bin Verzeichnis, aber das ist nicht notwendig, es wird nur erklären wie der Code I arbeitet später in Aufmachungen werden)
  • Edited meine .vbproj (oder `, csproj ') Datei, die alle Dateien in diesem Verzeichnis zu setzen (einschließlich Unterverzeichnisse) als zusätzliche Ressource-Dateien für mein Projekt
  • gemacht ein se Cond Edit zu meiner .vbproj Datei, um alle diese Ressourcen-Dateien in meine bin \ Debug oder bin \ Release-Verzeichnis zur Build-Zeit zu kopieren.

Zweitens, wie ich dies tun gelernt:

  • Joes solution above
  • This link zeigt, wie der Lage sein, in Platzhalter auf die .vbproj/CSPROJ Dateien hinzufügen, damit Sie hinzufügen in vollen Verzeichnissen gleichzeitig.
  • This answer, die zeigt, wie die Dateien auf meinem \ Bin-Verzeichnis kopieren

Schließlich meine Lösung:

  • ich meine project.vbproj Datei
  • Above öffnete die Linie <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />, fügte ich in einem neuen ItemGroup wie folgt aussehen:

<ItemGroup> <CommonFiles Include="Common Files\**" /> </ItemGroup>

Diese Lasten in allen Dateien (einschließlich aller Unterordner) und gibt, gebe ich die Build Action CommonFiles

  • Unter der Linie <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />, die ich in den folgenden Zeilen hinzugefügt:

    <PropertyGroup> <PrepareForRunDependsOn>$(PrepareForRunDependsOn);CopyCommonFiles</PrepareForRunDependsOn> </PropertyGroup>

<Target Name="CopyCommonFiles"> <Copy SourceFiles="@(CommonFiles)" DestinationFolder="$(OutDir)\%(RecursiveDir)" SkipUnchangedFiles="true"/> </Target>

Dadurch werden die Dateien aus dem CommonFiles Build Aktion in Ihrem bin \ Debug/bin \ Release-Verzeichnisse bei der Erstellung kopieren.

Und so habe ich es gemacht ....

irgendwelche Kommentare/Gedanken sind wirklich sehr geschätzt), wenn Sie denken, ich einen anderen Weg oder irgendetwas anderes) ....

diese

6

Sie können den .exe-Speicherort Ihrer App mit System.Reflection.Assembly.GetExecutingAssembly().Location abrufen.

string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location; 
string exeDir = System.IO.Path.GetDirectoryName(exePath); 
DirectoryInfo binDir = System.IO.Directory.GetParent(exeDir); 
+2

Wenn eine Assembly schattiert ist, enthält Assembly.Location den Speicherort nach dem Schattenkopieren. Eine bessere Lösung ist AppDomain.BaseDirectory zu verwenden: http://StackOverflow.com/a/6041505/13087 – Joe

1

Wenn Sie Konfigurationsdaten usw. haben, würde ich sie im Verzeichnis% Appdata% speichern. Dateien, die in das Installationsverzeichnis geändert werden könnten, sind keine gute Idee und sind seit Windows Vista verboten. Konfigurationsdaten sollten im Ordner% Appdata% gespeichert werden, der ein spezieller Ordner ist. Kodieren Sie den Pfad NICHT in Ihr Programm - Benutzer aus anderen Ländern oder 32/64bit Windowses werden schwerwiegende Probleme haben.

Eine gute Idee, wie man den Appdata-Ordner zugreifen, die Sie hier sehen können: How to create appdata folder with C#

+1

Dies ist nicht wirklich Konfigurationsdaten - Das ist mehr Dateien, die das Programm zur Laufzeit benötigt ... Ich bin etwas zögerlich Kopieren Sie sie ständig in den appdata-Ordner auf jedem Computer, da viele Benutzer dieses Programm nur einmal benutzen müssen und es sich in diesem Moment auf einem freigegebenen Laufwerk in meiner Organisation befindet ... Irgendwelche Gedanken dazu? –

+1

@ JohnBustos Das ist definitiv ein gültiger Punkt. Ich habe eine sehr ähnliche Coniguration bei der Arbeit und habe einfach einen Pfad in den Properties des Programms gespeichert. Da es als eine Einstellung gespeichert ist, ist es einfach, einen kleinen Bildschirm zu erstellen, der es dem Benutzer ermöglicht, einen neuen Dateispeicherort auszuwählen. Ich zögere, den Pfad fest zu codieren - das könnte sich in Zukunft ändern. –

0

folgenden Code aus http://msdn.microsoft.com/en-us/library/ms229654(v=vs.90).aspx

ist
String strAppDir = Path.GetDirectoryName(
     Assembly.GetExecutingAssembly().GetName().CodeBase); 
    String strFullPathToMyFile = Path.Combine(strAppDir, "fileName.txt"); 

    MessageBox.Show(String.Format("Path to the application is: '{0}'." + 
     "Full path to the file in the application folder is: '{1}'", 
     strAppDir, strFullPathToMyFile)); 
4

ich es tun würde, wie folgt:

  • Erstellen Sie einen Unterordner für die Dateien in Ihrem Projekt, z "Gemeinsame Dateien".

  • Legen Sie die Konfigurationsdateien in diesen Ordner. Stellen Sie ihre Eigenschaften auf:

    • Build Action = Inhalt

    • kopieren Ausgabeverzeichnis = kopieren immer (oder vielleicht auch: Kopieren wenn neuer)

  • Die Dateien werden dann kopiert werden zu bin \ Debug \ CommonFiles oder bin \ Release \ CommonFiles jedes Mal, wenn Ihre Anwendung erstellt wird.Sie können sie als Referenz:

    Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CommonFiles\MyFile.Dat"); 
    
+0

Das scheint die klügste Idee zu sein ... Sowohl für all diese Dateien, die wir benötigen, als auch für .dlls ... Nun, ich weiß, das mag seltsam klingen, aber es gibt wahrscheinlich etwa 50 Dateien in 10 oder so verschiedene Verzeichnisse, für die ich dies tun müsste (basierend auf Benutzereingaben, öffnet es eine bestimmte Datei) ... Gibt es eine Möglichkeit, diese Eigenschaften für das gesamte Verzeichnis auf einmal zu ändern, oder müsste ich diese Datei-by- Datei ... ODER, angesichts dieser neuen Daten, gibt es eine andere Weise, die Sie empfehlen würden ?? VIELEN DANK!!! –

+0

Ich denke, diese Technik eignet sich für eine relativ kleine Anzahl von Readonly-Konfigurationsdateien, wobei alle Dateien zum Zeitpunkt der Erstellung vorhanden sind. Wenn sie Dateien lesen/schreiben und/oder Benutzer zusätzliche Dateien hinzufügen können, würde ich dies nicht tun. Legen Sie die Dateien stattdessen an einem geeigneten Speicherort außerhalb des Ordners ab (in den der Benutzer schreiben kann, wenn sie Dateien lesen/schreiben), und fügen Sie Ihrer app.config eine Konfigurationseinstellung mit dem Verzeichnis hinzu, das die Dateien enthält. – Joe

+0

Danke, Joe - Sie sind nicht beschreibbar, nur Vorlagen, die auf dem Benutzer-Rechner gespeichert werden ... Nur eine Menge verschiedener Vorlagen und für verschiedene Zwecke, so in Unterordner .... Sie würden immer noch sagen, das zu tun mit der app.config ?? Wie würden Sie vorschlagen, dass das Beste getan werden sollte (vielleicht @ Tims Lösung mit Ihrem zusätzlichen Vorschlag/Bearbeitung ??? - Vielen Dank für Ihre anhaltende Hilfe! –

Verwandte Themen