2009-03-30 4 views
14

Tôi đang viết một IDE phát triển trò chơi để tạo và biên dịch các dự án .NET (mà tôi đã làm việc trong vài năm qua) và đang trong quá trình cập nhật nó để tạo đầu ra không chỉ cho Windows/Visual Studio, mà còn cho Linux/MonoDevelop (một quá trình rất đơn giản cho .NET, nhưng vẫn yêu cầu một số chỉnh sửa).Ai sao chép app.config vào app.exe.config?

Là một phần của điều này, tôi thấy cần thiết để bắt đầu tạo tệp app.config như một phần của điều này để ánh xạ các tên DLL phụ thuộc vào tên phụ thuộc Linux với các phần tử <dllmap>. Tôi đang bối rối về những người chịu trách nhiệm sao chép tệp app.config vào tên output.exe.config. Trong một dự án Visual Studio, Build Action cho app.config dường như thường được thiết lập là "None" và các thiết lập của nó chỉ ra rằng nó sẽ không được sao chép bất cứ đâu, nhưng khi Visual Studio biên dịch dự án nó tạo app.exe.config (mặc dù đôi khi tôi thấy điều này không đáng tin cậy). Khi tôi sử dụng MSBuild để xây dựng một tệp giải pháp được tạo ra bởi IDE (cho mục đích gỡ lỗi), MSBuild sao chép app.config thành app.exe.config. Nhưng khi tôi biên dịch dự án với CSharpCodeProvider.CompileAssemblyFromFile nó (tự nhiên) không thích tệp cấu hình được bao gồm dưới dạng mã nguồn ("app.config (1,1): lỗi CS0116: Không gian tên không trực tiếp chứa các thành viên như trường hoặc phương thức "), và tất nhiên nó không sao chép nó vào đầu ra khi tôi không đưa nó vào làm đầu vào. Có trách nhiệm của tôi để chỉ cần sao chép app.config để app.exe.config độc lập, hoặc là có một cách tiêu chuẩn hơn để làm điều này?

Có khó khăn khi lấy tệp * .config đầu tiên không? Trong IDE của tôi, có thể hiểu rằng tệp app.config sẽ được đổi tên hoặc tệp khác được thêm (giống như trong Visual Studio). Nó có vẻ kỳ lạ với tôi rằng IDE có hành động bí mật này để cấu hình các tập tin (tôi nghĩ MonoDevelop hoạt động tương tự như vậy trong vấn đề này bởi vì tôi không thể tìm thấy một hành động đặc biệt cho các tập tin cấu hình có một trong hai). Tôi không biết làm thế nào nó thậm chí còn chọn những tập tin mà hành động bí mật này áp dụng.

+0

Để làm rõ, câu hỏi của tôi là, kể từ khi tôi đang sử dụng CSharpCodeProvider để biên dịch mã (mà không cần đến một lệnh shell như MSBuild để lập dự án), cách chính xác để có được app.exe là gì .config trong đầu ra? – BlueMonkMN

+0

Tôi khuyên bạn nên sử dụng MSBuild trong IDE của bạn và tạo các tác vụ MSBuild cho bất kỳ đầu ra xây dựng đặc biệt nào mà bạn tạo ra, mà MSBuild không hỗ trợ. Điều này sẽ cho phép MSBuild biên dịch các giải pháp của bạn. Ngoài ra điều này sẽ làm cho sản phẩm của bạn dễ dàng hơn để tích hợp với tích hợp liên tục như TeamCity. – grover

+0

MSBuild có thể đã biên dịch các giải pháp của tôi. Và khi đó, nó đã được xử lý app.config một cách chính xác. CSharpCodeProvider có vẻ như là một giải pháp trực tiếp hơn với ít chi phí hơn là bắn phá MSBuild. IDE tạo ra một tệp giải pháp, nhưng không sử dụng nó khi biên dịch nội bộ. – BlueMonkMN

Trả lời

8

Trình biên dịch C# không quan tâm đến tệp cấu hình. Môi trường xây dựng (MSBuild và VS) sẽ tự lo việc sao chép tập tin đó.

+0

IDE của tôi không sử dụng MSBuild để biên dịch dự án. Nó đang sử dụng CSharpCodeProvider. Vậy IDE của tôi nên làm gì? – BlueMonkMN

+0

Nó sẽ sao chép tập tin cấu hình bằng cách sử dụng 'File.Copy' sau khi biên dịch. –

+0

Sao chép tệp * .config đầu tiên vào outputname.exe.config và bỏ qua bất kỳ tệp * .config nào khác có thể (không nên tồn tại)? – BlueMonkMN

1

Tôi nghĩ rằng MSBuild có trách nhiệm sao chép. Nếu bạn sẽ đào các tệp .target kho, thì có thể bạn sẽ tìm thấy các chỉ thị tương ứng. Bản thân VS không sao chép.

1

Cũng lưu ý rằng Visual Studio không xác thực tệp cấu hình.

7

thứ tự:

  1. đầu tiên file app.config với Không xây dựng hành động, trong thư mục dự án
  2. file app.config đầu tiên với xây dựng hành động nội dung, trong thư mục dự án
  3. app.config đầu tiên tệp có hành động Không xây dựng, trong thư mục con
  4. tệp app.config đầu tiên có hành động Xây dựng nội dung, trong thư mục con

msbuild/xbuild cũng cho phép bạn ghi đè điều này bằng cách thiết lập thuộc tính $ (AppConfig).

+0

Việc bạn đề cập đến thuộc tính '$ (AppConfig)' thực sự hữu ích đối với tôi. Tôi cảm thấy như bạn có thể cải thiện câu trả lời này với một số nền tảng hơn về nơi bạn tìm thấy thông tin này mặc dù. Tôi tìm thấy một số giải thích thêm [ở đây] (https://timvw.be/2008/03/17/easily-switching-between-appconfig-files-with-msbuild/) nhưng nếu có một liên kết chính thức thậm chí còn tốt hơn . Nếu không, chỉ cần đề cập đến tập tin 'target' sẽ được chào đón. – julealgon

0

Một câu trả lời hơi kỹ thuật - dự án của bạn tham chiếu Microsoft.CSharp.targets qua phím này trong file csproj:

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

Tập tin này sẽ giải quyết một cái gì đó giống như c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets, tùy thuộc vào phiên bản khuôn khổ của bạn.

Bên trong nó, bạn đã phần này mà làm việc:

<!-- 
    ============================================================ 
             _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> 

file app.config dường như được thông qua như là một biến môi trường (dự kiến ​​có mặt nhưng ai đặt nó, tôi don 't biết):

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

Edit: Đối app.config được chọn như thế nào, nhìn thấy câu trả lời này - https://stackoverflow.com/a/40293508/492336.

Việc xử lý app.config là đặc biệt, nó được xử lý theo Tên, quá trình xây dựng sẽ chọn file app.config theo trình tự sau đây:

  • Chọn giá trị $ (AppConfig) đặt trong dự án chính.
  • Chọn @ (Không) App.Config trong cùng thư mục với dự án.
  • Chọn @ (Nội dung) App.Config trong cùng thư mục với dự án.
  • Chọn @ (Không) App.Config trong bất kỳ thư mục con nào trong dự án.
  • Chọn @ (Nội dung) App.Config trong bất kỳ thư mục con nào trong dự án.