2009-03-30 13 views
14

Ich schreibe eine Spieleentwicklungs-IDE, die .NET-Projekte erstellt und kompiliert (an denen ich in den letzten Jahren gearbeitet habe) und diese gerade aktualisiere, um Ausgaben nicht nur für Windows/Visual Studio zu erzeugen, aber auch für Linux/MonoDevelop (ein aufregend einfacher Prozess für .NET, der aber immer noch ein paar Verbesserungen benötigt).Wer kopiert app.config in app.exe.config?

Als Teil davon habe ich gefunden, dass es notwendig ist, eine app.config-Datei als Teil davon zu erstellen, um abhängige DLL-Namen Linux-Abhängigkeitsnamen mit <dllmap> Elementen zuzuordnen. Ich bin verwirrt darüber, wer dafür verantwortlich ist, die app.config-Datei in den Ausgabenamen app.exe.config zu kopieren. In einem Visual Studio-Projekt scheint die Buildaktion für app.config normalerweise auf "None" festgelegt zu sein, und seine Einstellungen geben an, dass es nirgendwo kopiert wird. Wenn Visual Studio das Projekt jedoch kompiliert, generiert es app.exe.config (obwohl ich manchmal fand, dass das unzuverlässig ist). Wenn ich MSBuild verwende, um eine Lösungsdatei zu erstellen, die von der IDE (zu Debugzwecken) generiert wird, kopiert MSBuild app.config in app.exe.config. Aber wenn ich das Projekt mit CSharpCodeProvider.CompileAssemblyFromFile kompiliere, mag es (natürlich) nicht, dass die Konfigurationsdatei als Quellcode enthalten ist ("app.config (1,1)"): Fehler CS0116: Ein Namespace enthält nicht direkt Elemente wie Felder oder Methoden "), und natürlich kopiert es es nicht zur Ausgabe, wenn ich es nicht als eine Eingabe einschließen. Ist es in meiner Verantwortung, app.config einfach in app.exe.config zu kopieren, oder gibt es dafür eine Standardmethode?

Ist die erste * .config-Datei fest installiert? In meiner IDE ist es denkbar, dass die Datei app.config umbenannt oder eine andere hinzugefügt wird (genau wie in Visual Studio). Es erscheint mir komisch, dass die IDE diese geheime Aktion für Konfigurationsdateien hat (ich denke MonoDevelop verhält sich in dieser Hinsicht ähnlich, weil ich dort auch keine spezielle Aktion für die Konfigurationsdateien finden konnte). Ich weiß nicht, wie es überhaupt zu welchen Dateien diese geheime Aktion passt.

+0

Um zu klären, meine Frage ist, da ich CSharpCodeProvider bin mit dem Code zu kompilieren (ohne wie MSBuild zu einem Shell-Befehl zurückgreifen, das Projekt zu kompilieren), was der richtige Weg ist, um die app.exe zu erhalten .config in der Ausgabe? – BlueMonkMN

+0

Ich würde vorschlagen, MSBuild in Ihrer IDE zu verwenden und MSBuild-Aufgaben für jede spezielle Build-Ausgabe zu erstellen, die Sie generieren, für die MSBuild keine Unterstützung bietet. Dies würde MSBuild ermöglichen, zu Ihren Lösungen zu kompilieren. Darüber hinaus erleichtert dies die Integration Ihres Produkts in die kontinuierliche Integration wie TeamCity. – grover

+0

MSBuild kann meine Lösungen bereits kompilieren. Und wenn dies der Fall ist, wird app.config bereits korrekt verarbeitet. CSharpCodeProvider scheint eine direktere Lösung mit weniger Overhead als MSBuild zu sein. Die IDE generiert eine Lösungsdatei, verwendet diese jedoch nicht, wenn sie intern kompiliert wird. – BlueMonkMN

Antwort

8

Der C# -Compiler kümmert sich überhaupt nicht um die Konfigurationsdatei. Buildumgebungen (MSBuild und VS) sorgen dafür, dass diese Datei selbst kopiert wird.

+0

Meine IDE verwendet MSBuild nicht zum Kompilieren des Projekts. Es verwendet CSharpCodeProvider. Was also sollte meine IDE tun? – BlueMonkMN

+0

Es sollte die Konfigurationsdatei mit 'File.Copy' nach dem Kompilieren kopieren. –

+0

Kopieren Sie die erste * .config-Datei in outputname.exe.config und ignorieren Sie alle möglichen anderen * .config-Dateien (die nicht existieren sollten)? – BlueMonkMN

1

Ich denke, MSBuild ist verantwortlich für das Kopieren. Wenn Sie die .target-Dateien für den Lagerbestand durchsuchen würden, würden Sie wahrscheinlich entsprechende Anweisungen finden. VS selbst kopiert nicht.

1

Beachten Sie auch, dass Visual Studio die Konfigurationsdatei überprüft.

7

Auftrag:

  1. erste app.config-Datei mit keinem Von Aktion im Projektverzeichnis
  2. erste app.config-Datei mit Inhalt Build-Aktion im Projektverzeichnis
  3. ersten app.config Datei mit keinem Von Aktion, in einem Unterverzeichnis
  4. erste app.config-Datei mit Inhalt Build-Aktion, in einem Unterverzeichnis

msbuild/xbuild können Sie auch überschreiben, indem Sie die Eigenschaft $ (AppConfig) festlegen.

+0

Ihre Erwähnung der '$ (AppConfig)' Eigenschaft war sehr hilfreich für mich. Ich habe das Gefühl, dass Sie diese Antwort mit mehr Hintergrundinformationen darüber, wo Sie diese Informationen gefunden haben, verbessern können. Ich fand einige zusätzliche Erklärungen [hier] (https://timvw.be/2008/03/17/easily-switching-between-appconfig-files-with-msbuild/), aber wenn es einen offiziellen Link gibt, der noch besser wäre . Wenn nicht, wäre auch eine Erwähnung der Datei "targets" willkommen. – julealgon

0

Eine etwas technische Antwort - Ihr Projekt verweist Microsoft.CSharp.targets über diese Taste in der csproj Datei:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 

Diese Datei zu so etwas wie c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets, abhängig von Ihrer Framework-Version würde lösen.

Innerhalb von ihm Ihnen diesen Abschnitt haben, der die Arbeit macht:

<!-- 
    ============================================================ 
             _CopyAppConfigFile 

    Copy the application config file. 
    ============================================================ 
    --> 
    <Target 
     Name="_CopyAppConfigFile" 
     Condition=" '@(AppConfigWithTargetPath)' != '' " 
     Inputs="@(AppConfigWithTargetPath)" 
     Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"> 

    <!-- 
     Copy the application's .config file, if any. 
     Not using SkipUnchangedFiles="true" because the application may want to change 
     the app.config and not have an incremental build replace it. 
     --> 
    <Copy 
     SourceFiles="@(AppConfigWithTargetPath)" 
     DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" 
     OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)" 
     Retries="$(CopyRetryCount)" 
     RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" 
     UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)" 
      > 

     <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/> 

    </Copy> 

    </Target> 

Die App.Config Datei scheint als Umgebungsvariable übergeben werden (es wird erwartet, anwesend zu sein, aber wer setzt es, ich don ‚t wissen):

<ItemGroup> 
    <AppConfigWithTargetPath Include="$(AppConfig)" Condition="'$(AppConfig)'!=''"> 
    <TargetPath>$(TargetFileName).config</TargetPath> 
    </AppConfigWithTargetPath> 
</ItemGroup> 

Edit: Für wie app.config ausgewählt ist, sehen Sie diese Antwort - https://stackoverflow.com/a/40293508/492336.

Der Umgang mit app.config Sonder ist es nach Name, wählt der Build-Prozess die Datei app.config in dieser Reihenfolge anschließen behandelt wird:

den Wert $ (AppConfig) in
  • wählen gesetzt das Hauptprojekt.
  • Wählen Sie @ (None) App.Config im selben Ordner wie das Projekt.
  • Wählen Sie @ (Content) App.Config im selben Ordner wie das Projekt.
  • Wählen Sie @ (None) App.Config in einem beliebigen Unterordner im Projekt.
  • Wählen Sie @ (Content) App.Config in einem beliebigen Unterordner im Projekt.