2012-01-05 72 views
8

Tôi đang làm việc trên một dự án tạo trình tạo mã để tạo giải pháp với các lớp có thể tùy chỉnh. bây giờ tôi có thể tạo tệp .sln bằng cách viết tất cả các phần tử trong mã. nhưng các tệp dự án không cần điều này, chúng có thể được chỉnh sửa bằng cách sử dụng lớp MSBuild Project.Làm thế nào để tạo tệp Visual Studio Solution (.sln) theo lập trình, bao gồm các dự án Website?

Tôi muốn thêm hỗ trợ mẫu dự án trang web và v.v., vì vậy cách này tôi chỉnh sửa tệp .sln không phải là tuyệt vời, tôi muốn biết đó là cách tốt hơn để thực hiện việc này, như MSBuild hay cái gì khác?

Tôi thấy Programmatically generate Visual Studio Solution nói rằng sử dụng Visual Studio SDK (dành cho studio mở rộng, viết plugin ...), nhưng không có mẫu mã nào.

cảm ơn trước

+3

Dự án trang web không tốt cho bạn. Sử dụng các dự án ứng dụng Web và những dự án đó có thể được thao tác với MSBuild. – Svarog

+0

Tôi đã hỏi một cái gì đó tương tự trước đây: stackoverflow.com/questions/8064675/. Rõ ràng bạn có thể làm điều đó bằng cách sử dụng EnvDTE, tuy nhiên tôi đã gặp khó khăn khi nhận được rằng để làm việc –

+0

Có lẽ bạn có thể sử dụng một cái gì đó như Premake để tạo ra các tập tin dự án? http://industriousone.com/premake – eandersson

Trả lời

5

Dưới đây là làm thế nào để sử dụng SLNTools để tạo file sln trong mã. Mã là một mớ hỗn độn! Nhưng nó đã có tác dụng!

Dự án SLN Tools có thể tạo tệp sln từ tệp dự án. Đó là mã nguồn mở và nó cung cấp giao diện người dùng để chỉnh sửa và hợp nhất các tệp sln. Trong trường hợp này, bạn có thể sử dụng dự án cốt lõi và bằng cách tham khảo 'CWDev.SLNTools.Core.dll' trong dự án của bạn, bạn có thể viết một messy (!) như sau:

LƯU Ý: Một số phần của lớp không được hiển thị ở đây và cũng có một số đối tượng tùy chỉnh của dự án của riêng tôi như Sln, Project và ... không nên nhầm với SLNTools Objects . Tôi đã bình luận bất cứ nơi nào cần thiết!

using CWDev.SLNTools.Core; 
using SlnFile = CWDev.SLNTools.Core.SolutionFile; 
using SlnProject = CWDev.SLNTools.Core.Project; 
using SeptaCodeGenerator.Core.IO; 

public class SlnFileManager 
{ 
    // * Note: Sln is of my own type. 
    Sln _sln; 
    // * SolutionFile is the type in SLNTools project that we use 
    SlnFile _slnFile; 

    public void WriteNewSlnFile(Sln slnObject) 
    { 
     _sln = slnObject; 
     _slnFile = new SlnFile(); // or you can read sln file like below 
     using (SolutionFileReader reader = new SolutionFileReader(_sln.ObjectFullPath)) 
      _slnFile = reader.ReadSolutionFile(); 
     AddHeaders(); 
     AddGlobalSections(); 
     // add projects 
     List<SolutionNode> sns = _sln.GetAllSubItemsOf(typeof(SolutionFolder), typeof(ProjectNode)); 
     foreach (SolutionNode sn in sns) 
      _slnFile.Projects.Add(CreateProject(sn)); 

     using (SolutionFileWriter writer = new SolutionFileWriter(_sln.ObjectFullPath)) 
      writer.WriteSolutionFile(_slnFile); 
    } 

    // this is how I create and add project sections, using Section and PropertyLine 
    private SlnProject CreateProject(SolutionNode sn) 
    { 
     List<Section> projectSections = CreateProjectSections(sn); 
     List<PropertyLine> versionControlLines = CreateVersionControlLines(sn); 
     List<PropertyLine> projectConfigurationPlatformsLines = CreateProjectConfigurationPlatformsLines(sn); 

     string parentGuid = (sn.Parent is Sln ? null : sn.Parent.InstanceGuidSt); 
     string relativePath = (sn is Project) ? (sn as Project).ProjFile.ObjectRelativePath : sn.ObjectRelativePath; 
     return new CWDev.SLNTools.Core.Project(_slnFile, sn.InstanceGuidSt, sn.TypeGuidSt, sn.Name, relativePath, parentGuid, 
      projectSections, versionControlLines, projectConfigurationPlatformsLines); 
    } 

    // this method creates ProjectSections(WebsiteProperties) 
    private List<Section> CreateProjectSections(SolutionNode project) 
    { 
     Section sec = null; 
     var lines = new List<PropertyLine>(); 
     if (project is SolutionFolder) 
     { 
      List<SolutionNode> files = project.GetAllSubItemsOf(typeof(SolutionFile)); 
      foreach (SolutionNode item in files) 
      { 
       // * consideration required 
       lines.Add(new PropertyLine(item.ObjectRelativePath, item.ObjectRelativePath)); 
      } 
      if (lines.Count > 0) 
       sec = new Section("SolutionItems", "ProjectSection", "preProject", lines); 
     } 
     // *** here is the code that I wrote to add website projects *** 
     else if (project is WebSiteProject) 
     { 
      var website = project as WebSiteProject; 
      if (_sln.IsUnderSourceControl) 
      { 
        lines.AddRange(new PropertyLine[] 
        { 
         new PropertyLine("SccProjectName", "\"SAK\""), 
         new PropertyLine("SccAuxPath", "\"SAK\""), 
         new PropertyLine("SccLocalPath", "\"SAK\""), 
         new PropertyLine("SccProvider", "\"SAK\"") 
        }); 

      } 
      if (_sln.SolutionVersion == SolutionFileVersion.V11VS2010) 
       lines.Add(new PropertyLine("TargetFrameworkMoniker", "\".NETFramework,Version%3Dv4.0\"")); 
      else 
       lines.Add(new PropertyLine("TargetFramework", "\"3.5\"")); 
      // add project references 
      string projectReferences = ""; 
      foreach (Project proj in website.ReferencedProjects) 
       projectReferences += proj.InstanceGuidSt + "|" + proj.ClassName + ".dll;"; 
      lines.Add(new PropertyLine("ProjectReferences", "\"" + projectReferences + "\"")); 

      string debugConf = "Debug.AspNetCompiler."; 
      string releaseConf = "Release.AspNetCompiler."; 
      string str = debugConf; 
      int k = 0; 
      while (k < 2) 
      { 
       // other properties 
       lines.AddRange(new PropertyLine[] 
       { 
        new PropertyLine(str + "VirtualPath", "\"/" + website.Name + "\""), 
        new PropertyLine(str + "PhysicalPath", "\"" + website.ObjectRelativePath + "\\\""), 
        new PropertyLine(str + "TargetPath", ("\"PrecompiledWeb\\" + website.Name + "\\\"")), 
        new PropertyLine(str + "Updateable", "\"true\""), 
        new PropertyLine(str + "ForceOverwrite", "\"true\""), 
        new PropertyLine(str + "FixedNames", "\"false\""), 
        new PropertyLine(str + "Debug", (k == 0 ? "\"True\"" : "\"False\"")) 
       }); 

       if (k++ == 0) 
        str = releaseConf; 
      } 
      Random rand = new Random(); 
      lines.Add(new PropertyLine("VWDPort", "\"" + rand.Next(1111, 65000).ToString() + "\"")); 
      lines.Add(new PropertyLine("DefaultWebSiteLanguage", 
       website.Language == SeptaCodeGenerator.Core.Language.CodeLanguage.CSharp ? "\"Visual C#\"" : "\"Visual Basic\"")); 

      sec = new Section("WebsiteProperties", "ProjectSection", "preProject", lines); 
     } 
     var sections = new List<Section>(); 
     if (sec != null) 
      sections.Add(sec); 
     return sections; 
    } 
} 

Hy vọng điều đó sẽ hữu ích.

0

Trong tệp giải pháp của tôi, dự án trang web được lưu trữ trong phần dự án WebsiteProperties. Các thuộc tính này được chuyển vào aspnet_compiler như các tham số đầu vào tùy thuộc vào cấu hình xây dựng. Cố gắng tìm kiếm projectID (GUID) (C9683FA5-AABA-497F-B780-80EFC3EB81F2 trong trường hợp này) bên trong các tệp sln của bạn có chứa dự án trang web, những phần nào của tệp sln sẽ được cập nhật/tạo bởi trình tạo mã của bạn.

Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "MasterData.Host", "..\..\Customs.Framework\Services\MasterDataService\Tests\MasterData.Host", "{C9683FA5-AABA-497F-B780-80EFC3EB81F2}" 
    ProjectSection(WebsiteProperties) = preProject 
     SccProjectName = "SAK" 
     SccAuxPath = "SAK" 
     SccLocalPath = "SAK" 
     SccProvider = "SAK" 
     TargetFrameworkMoniker = ".NETFramework,Version%3Dv3.5" 
     ProjectReferences = "{C7C785E8-89E6-459A-969C-BFC2BC7E8ED2}|Porthus.Customs.Framework.Services.MasterData.ServiceImplementation.dll;{ADFA3898-854C-4058-8726-523EA8802FFD}|Porthus.Customs.Framework.Services.MasterData.FaultContracts.dll;{9A565742-4843-40A6-A2E3-2B432573D12B}|Porthus.Customs.Framework.Services.MasterData.MessageContracts.dll;{E8B5D2A1-E934-4C85-AB71-A2148050913A}|Porthus.Customs.Framework.Services.MasterData.ServiceContracts.dll;{3C752087-CED2-499F-AF3B-84E1548229CB}|Porthus.Customs.Services.MasterData.BusinessEntities.dll;{437C651C-3C8D-4B3D-B967-E58DBCD83EE4}|Porthus.Customs.Services.MasterData.BusinessLogic.dll;{59BBDE80-6F20-4FB6-A65B-68BC584AD2CB}|Porthus.Customs.Services.MasterData.DataAccess.dll;" 
     Debug.AspNetCompiler.VirtualPath = "/MasterData.Host" 
     Debug.AspNetCompiler.PhysicalPath = "..\..\Customs.Framework\Services\MasterDataService\Tests\MasterData.Host\" 
     Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\MasterData.Host\" 
     Debug.AspNetCompiler.Updateable = "true" 
     Debug.AspNetCompiler.ForceOverwrite = "true" 
     Debug.AspNetCompiler.FixedNames = "false" 
     Debug.AspNetCompiler.Debug = "True" 
     Release.AspNetCompiler.VirtualPath = "/MasterData.Host" 
     Release.AspNetCompiler.PhysicalPath = "..\..\Customs.Framework\Services\MasterDataService\Tests\MasterData.Host\" 
     Release.AspNetCompiler.TargetPath = "PrecompiledWeb\MasterData.Host\" 
     Release.AspNetCompiler.Updateable = "true" 
     Release.AspNetCompiler.ForceOverwrite = "true" 
     Release.AspNetCompiler.FixedNames = "false" 
     Release.AspNetCompiler.Debug = "False" 
     VWDPort = "1333" 
     DefaultWebSiteLanguage = "Visual C#" 
    EndProjectSection 
EndProject 

Bạn nên cập nhật (ít nhất) ProjectConfigurationPlatforms & NestedProjects phần toàn cầu. Điều này là cần thiết trong trường hợp của tôi.

Tôi đã triển khai giải pháp hợp nhất tác vụ MsBuild. Nó hỗ trợ kết hợp nhiều tệp giải pháp vào một tệp MergedSolution.sln. Nó hoạt động trên 20 tệp giải pháp có chứa hơn 500 dự án của chúng tôi (C# & trang web & các tệp/phần dự án sql db). Dung lượng tệp giải pháp đầu ra là 1,3MB :)

EDIT: SLN Tools project có thể tạo tệp sln từ tệp dự án.

Làm thế nào để tạo ra file SLN với tùy chỉnh MSBuild nhiệm vụ:

  • Here là thông tin tốt về dạng dung dịch và hồ sơ dự án.
  • Nếu bạn có một bộ hồ sơ dự án, bạn có thể tạo tập tin giải pháp của bạn bởi custom MSBuild task (bên Execute method)
  • Để đọc các tập tin dự án MSBuild sử dụng Microsoft.Build.BuildEngine.Project lớp (nó là lỗi thời nhưng tôi vẫn đang sử dụng nó) hoặc Microsoft.Build.Evaluation.Project lớp
+0

cảm ơn, Vì vậy, bạn đã làm tất cả chính mình, bạn đã đưa ra một công cụ, lớp học hay một cái gì đó? – Ashkan

+0

Tôi đang sử dụng tác vụ MSBuild tùy chỉnh, nhưng tôi không thể xuất bản mã nguồn - quy tắc công ty, xin lỗi: ( – Ludwo

+0

Vâng, bạn có thể đưa ra gợi ý về cách tạo tệp .sln với tác vụ msbuild không? Tôi nghĩ đây là cách tốt nhất để tạo các tệp sln, như tôi làm cho các tệp dự án (. ?? proj). Nếu nó hoạt động, tôi sẽ đánh dấu nó là câu trả lời. – Ashkan

1

Bạn có thể sử dụng giao diện IVsSolution để tạo giải pháp và thêm dự án cho chúng. Bạn vượt qua trong các loại SVsSolution với phương pháp GetService() để có được một thể hiện của giao diện đó như sau:

var solution = (IVsSolution)GetService(typeof(SVsSolution)); 
+0

Tôi nghĩ rằng công trình này! Nhưng tôi không cần phải sử dụng tương tác sutdio trực quan, tuy nhiên, có vẻ như không có công cụ nào có sẵn chính xác cho những gì tôi cần. – Ashkan

Các vấn đề liên quan