2013-11-14 7 views
5

Sto scrivendo un .Net WinForms e cambio continuamente tra le configurazioni DEBUG e RELEASE e ho alcuni file per i quali ho bisogno di entrambe le configurazioni.Environment.CurrentDirectory vs System.IO.Directory.GetCurrentDirectory

Quello che stavo pensando di fare era di mettere i file in una directory comune nella cartella bin quindi sarebbe simile a questa:

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

e stavo pensando su come accedere alle file utilizzando qualcosa sulla falsariga di:

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

la mia domanda è se questo è pericoloso, in quanto, da quello che ho letto, System.IO.Directory.GetCurrentDirectory potrebbe cambiare a causa all'utente la selezione di una nuova directory corrente, per esempio, una finestra di dialogo file aperto.

Dovrei piuttosto usare qualcosa sulla falsariga di:

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

O c'è un modo migliore per arrivare alla cartella /Bin in modo da poter passare da lì o un generalmente accettato modo/posizione per archivi i file che il programma di solito ha bisogno di raggiungere e il modo per fare riferimento più facilmente (forse qualcosa che è fatto per funzionare con qualsiasi tipo di app e non solo WinForms)?

+0

La directory bin è un dettaglio di implementazione del sistema di VS costruire . Poiché è improbabile che spedirai il tuo progetto con codice sorgente al cliente e non sarai in grado di salvare i file in c: \ program files \ bin, questa non è una buona pratica. Utilizzare% appdata% per i file scrivibili, la directory EXE o% programdata% per i file di sola lettura. –

+0

Grazie a @HansPassant ... Come ho detto a Christian di seguito, sono un po 'titubante a copiarli costantemente nella cartella appdata sul computer di ciascun utente, poiché molti utenti dovranno utilizzare questo programma una sola volta e sarà su un'unità condivisa nella mia organizzazione a questo punto ... qualche pensiero a riguardo ?? –

risposta

3

Sebbene la maggior parte delle risposte ha in realtà sembrano funzionare, the solution offered by Joe above, dopo un po 'di tweaking, ha dimostrato di essere la soluzione migliore per la mia situazione.


In primo luogo, la soluzione finale sono andato con:

  • creata una directory Common Files (Nel mio caso, allo stesso livello come il mio elenco Bin, ma non è necessario, sarà solo a spiegare come il codice metterò più tardi funziona)
  • modificato il mio .vbproj di file (o `, csproj ') per impostare tutti i file in quella directory (incluse le sottodirectory) come file di risorse in più per il mio progetto
  • Realizzato un se cond edit al mio file .vbproj per copiare tutti quei file di risorse nella mia directory bin \ Debug o bin \ Release al momento della compilazione.

In secondo luogo, come ho imparato a fare questo:

  • Joes solution above
  • This link mostra come essere in grado di aggiungere in caratteri jolly per i/Csproj file vbproj modo da poter aggiungere in directory complete contemporaneamente.
  • This answer che mostra come copiare i file nella mia directory \ bin

Infine, la mia soluzione:

  • ho aperto il mio file project.vbproj
  • Sopra la linea <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />, ho aggiunto un nuovo ItemGroup con il seguente aspetto:

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

Questa carichi in tutti i file (incluse tutte le sottocartelle) e mi dà l'Operazione di generazione CommonFiles

  • Sotto la linea <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />, ho aggiunto le seguenti righe:

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

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

Questo copierà i file dalla azione CommonFiles accumulo nelle vostre bin \ Debug/bin \ Stampa directory in fase di compilazione.

Ed è così che l'ho fatto ....

qualsiasi commento/i pensieri sono davvero molto apprezzate) se pensi avrei dovuto usare un altro modo o qualsiasi altra cosa) ....

questo

6

È possibile ottenere la posizione .exe della propria app con System.Reflection.Assembly.GetExecutingAssembly().Location.

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

Se un assieme viene copiato dall'ombra, Assembly.Location contiene il percorso dopo essere stato copiato dall'ombra. Una soluzione migliore è usare AppDomain.BaseDirectory: http://stackoverflow.com/a/6041505/13087 – Joe

1

Se si dispone di dati di configurazione, ecc. Li memorizzerei nella directory% Appdata%. L'inserimento di file che potrebbero essere modificati nella directory di installazione non è una buona idea ed è vietato da Windows Vista. I dati di configurazione devono essere archiviati nella cartella% Appdata%, che è una cartella speciale. NON codificare il proprio percorso nel proprio programma: gli utenti di paesi stranieri o le finestre a 32/64 bit avranno gravi problemi.

Una buona idea su come accedere al Appdata-Folder si può vedere qui: How to create appdata folder with C#

+1

Questo non è proprio un dato di configurazione - Questo è più file di cui il programma ha bisogno in fase di esecuzione ... Sono un po 'titubante copiarli costantemente nella cartella appdata sul computer di ogni oser poiché molti utenti avranno bisogno di usare questo programma solo una volta ed è su un'unità condivisa nella mia organizzazione a questo punto ... Qualche idea a riguardo ?? –

+1

@JohnBustos Questo è sicuramente un punto valido. Ho una Conigurazione molto simile al lavoro e ho semplicemente memorizzato un Percorso nelle Proerties del programma. Poiché è memorizzato come impostazione, è facile creare un piccolo schermo che consenta all'utente di selezionare un nuovo percorso file. Sono riluttante a hardcode il percorso - potrebbe cambiare in futuro. –

0

seguito il codice è da http://msdn.microsoft.com/en-us/library/ms229654(v=vs.90).aspx

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

lo farei come segue:

  • Creare una sottocartella per i file nel progetto, ad es "File comuni".

  • Inserire i file di configurazione in questa cartella. Impostare le loro proprietà per:

    • Corporatura Action = Content

    • Copia nella directory di output = Copia sempre (o forse: Copia se più recente)

  • saranno quindi copiato i file in bin \ Debug \ CommonFiles o bin \ Release \ CommonFiles ogni volta che viene creata l'applicazione.È possibile fare riferimento come:

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

Questa sembra l'idea più intelligente ... Entrambi per tutti questi file avremo bisogno e anche per .dlls necessari ... Ora, so che questo potrebbe sembrare strano, ma ci sono probabilmente circa 50 circa file in 10 o giù di lì diverse directory avrei bisogno di fare questo per (basato su input dell'utente, apre un file specifico) ... C'è un modo per cambiare queste proprietà per l'intera directory in una volta, o dovrei fare questo file-by- file ... O, dato questo nuovo bit di dati, c'è un modo diverso che consiglieresti ?? GRAZIE!!! –

+0

Penso che questa tecnica sia appropriata per un numero relativamente piccolo di file di configurazione di sola lettura, con tutti i file esistenti al momento della compilazione. Se sono file di lettura/scrittura e/o gli utenti possono aggiungere file aggiuntivi, non lo farei. Mettete invece i file in una posizione adatta al di fuori della cartella bin (a cui l'utente può scrivere se sono file di lettura/scrittura) e aggiungete un'impostazione di configurazione al vostro app.config con la directory che contiene i file. – Joe

+0

Grazie, Joe - Non sono scrivibili, solo i modelli che vengono salvati sul computer dell'utente ... Solo un sacco di diversi modelli e per scopi diversi, quindi nelle sottocartelle .... Si direbbe ancora di farlo con l'app.config ?? Come suggeriresti che fosse meglio fare (forse la soluzione di Tim con il tuo suggerimento/modifica ??? - Grazie ancora per il tuo aiuto continuato !! –

Problemi correlati