2012-01-05 18 views
8

मैं कोड जनरेटर प्रोजेक्ट पर काम कर रहा हूं जो अनुकूलन परतों के साथ समाधान बनाता है। अब के लिए मैं कोड में सभी तत्वों को लिखकर .sln फ़ाइल बनाने में सक्षम हूं। लेकिन परियोजना फ़ाइलों को इसकी आवश्यकता नहीं है, उन्हें एमएसबिल्ड परियोजना वर्ग का उपयोग करके संपादित किया जा सकता है।वेबसाइट प्रोजेक्ट समेत, विजुअल स्टूडियो सॉल्यूशन (.sln) फ़ाइलों को प्रोग्रामेटिक रूप से कैसे बनाएं?

मैं एक वेबसाइट प्रोजेक्ट टेम्पलेट समर्थन और आदि जोड़ना चाहता हूं, इसलिए इस तरह से मैं .sln फ़ाइल संपादित करता हूं, यह अच्छा नहीं है, मैं जानना चाहता हूं कि ऐसा करने का कोई बेहतर तरीका है, जैसे MSBuild या कुछ और?

मैंने Programmatically generate Visual Studio Solution देखा जो विजुअल स्टूडियो एसडीके (जो विजुअल स्टूडियो को विस्तारित करने, प्लगइन लिखने के लिए है ...) का उपयोग करने के लिए कहता है, लेकिन कोई कोड नमूना नहीं है। अग्रिम

+3

वेब साइट परियोजनाएं आपके लिए खराब हैं। वेब अनुप्रयोग परियोजनाओं का प्रयोग करें, और उनको एमएसबिल्ड के साथ निश्चित रूप से छेड़छाड़ की जा सकती है। – Svarog

+0

मैंने पहले कुछ इसी तरह से पूछा: stackoverflow.com/questions/8064675/। जाहिर है आप इसे EnvDTE का उपयोग करके कर सकते हैं, हालांकि मुझे –

+0

पर काम करने में परेशानी हो रही है शायद आप प्रोजेक्ट फ़ाइलों को उत्पन्न करने के लिए Premake जैसे कुछ उपयोग कर सकते हैं? http://industriousone.com/premake – eandersson

उत्तर

5

यहाँ कैसे कोड में SLN फ़ाइल बनाने के लिए SLNTools उपयोग करने के लिए है। कोड एक गड़बड़ है! लेकिन यह काम करता है!

एसएलएन टूल्स प्रोजेक्ट प्रोजेक्ट फ़ाइलों से एसएलएन फाइल बनाने में सक्षम है। यह खुला स्रोत है और यह संपादन और विलय फ़ाइलों को विलय करने के लिए यूआई प्रदान करता है। इस मामले में आप कोर प्रोजेक्ट का उपयोग कर सकते हैं और 'प्रोजेक्ट में' CWDev.SLNTools.Core.dll 'का संदर्भ देकर आप एक गन्दा लिख ​​सकते हैं (!) इस तरह कोड:

नोट: वर्ग के कुछ हिस्सों यहां दिए गए हैं नहीं है और यह भी SLN, परियोजना की तरह अपने ही परियोजना के कुछ कस्टम वस्तुओं नहीं है और ... कि SLNTools साथ गलत नहीं किया जाना चाहिए ही नाम के साथ ऑब्जेक्ट्स । मैंने whereever की जरूरत टिप्पणी की!

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; 
    } 
} 

उम्मीद है कि यह मदद करता है।

0

मेरी समाधान फाइलों में में

धन्यवाद, वेब साइट परियोजनाओं WebsiteProperties परियोजना खंड में जमा हो जाती है। बिल्ड गुण कॉन्फ़िगरेशन के आधार पर इन गुणों को इनपुट पैरामीटर के रूप में aspnet_compiler में पास किया गया है। प्रोजेक्ट आईडी (GUID) (C9683FA5-AABA-497F-B780-80EFC3EB81F2) को इस मामले में खोजने के लिए प्रयास करें) वेबसाइट प्रोजेक्ट वाली आपकी एसएलएन फाइलों के अंदर, स्लन फ़ाइल के कौन से हिस्से आपके कोड जनरेटर द्वारा अपडेट/जेनरेट किए जाने चाहिए।

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 

आप (कम से कम) ProjectConfigurationPlatforms & NestedProjects वैश्विक वर्गों अद्यतन करना चाहिए। मेरे मामले में इसकी आवश्यकता थी।

मैंने मर्ज समाधान एमएसबिल्ड कार्य को लागू किया है। यह एक MergedSolution.sln फ़ाइल में एकाधिक समाधान फ़ाइलों के विलय का समर्थन करता है। यह 500+ परियोजनाओं (सी # & वेबसाइट & एसक्यूएल डीबी परियोजना फाइल/अनुभाग) वाली हमारी 20+ समाधान फ़ाइलों पर काम करता है। आउटपुट समाधान फ़ाइल का आकार 1.3 एमबी है :)

संपादित करें: SLN Tools project प्रोजेक्ट फ़ाइलों से एसएलएन फ़ाइल बनाने में सक्षम है।

  • Here समाधान और प्रोजेक्ट फ़ाइलें प्रारूप के बारे में अच्छी जानकारी है:

    कैसे कस्टम MSBuild कार्य के साथ SLN फ़ाइल उत्पन्न करने के लिए।

  • आप परियोजना फ़ाइलों का एक सेट है, तो आप अपने समाधान फ़ाइल custom MSBuild task द्वारा (अंदर विधि निष्पादित करें)
  • पढ़ने के लिए MSBuild परियोजना फाइलों Microsoft.Build.BuildEngine.Project क्लास का उपयोग उत्पन्न कर सकते हैं (यह अप्रचलित है लेकिन मैं अभी भी यह उपयोग कर रहा हूँ) या माइक्रोसॉफ्ट.बिल्ड। मूल्यांकन। प्रोजेक्ट क्लास
+0

धन्यवाद, तो आपने यह सब किया है, क्या आप एक उपकरण, कक्षा या कुछ के साथ आए थे? – Ashkan

+0

मैं कस्टम एमएसबिल्ड कार्य का उपयोग कर रहा हूं, लेकिन मैं स्रोत कोड - कंपनी नियम प्रकाशित नहीं कर सकता, क्षमा करें :( – Ludwo

+0

हाँ, क्या आप एमएसबिल्ड कार्य के साथ .sln फ़ाइल बनाने के तरीके पर एक संकेत दे सकते हैं? मुझे लगता है कि यह सबसे अच्छा तरीका है एसएलएन फाइलें बनाएं, जैसा कि मैं प्रोजेक्ट (। ?? proj) फ़ाइलों के लिए करता हूं। अगर यह काम करता है, तो मैं इसे उत्तर के रूप में चिह्नित करने जा रहा हूं। – Ashkan

1

आप समाधान बनाने और परियोजनाओं को जोड़ने के लिए IVsSolution इंटरफ़ेस का उपयोग कर सकते हैं। आप GetService() विधि के लिए SVsSolution प्रकार में भेजेंगे, ताकि जैसे कि इंटरफ़ेस का एक उदाहरण प्राप्त करने के लिए:

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

मुझे लगता है कि यह काम करता है! लेकिन मुझे दृश्य सूटडियो इंटरऑप का उपयोग न करने की आवश्यकता है, हालांकि, ऐसा लगता है कि मुझे जो चाहिए वह बिल्कुल उपलब्ध नहीं है। – Ashkan

संबंधित मुद्दे

 संबंधित मुद्दे