ভিজ্যুয়াল স্টুডিও সমাধান ফাইলগুলি পার্স করা হচ্ছে


109

আমি কীভাবে। নেট এ ভিজ্যুয়াল স্টুডিও সমাধান (এসএলএন) ফাইলগুলি পার্স করতে পারি? আমি এমন একটি অ্যাপ্লিকেশন লিখতে চাই যা আপেক্ষিক বিল্ড অর্ডারটি সংরক্ষণ করার সময় একাধিক সমাধানকে একত্রে মিশিয়ে দেয়।

উত্তর:


113

মাইক্রোসফ্ট। বিল্ড অ্যাসেমব্লির .NET 4.0 সংস্করণে মাইক্রোসফ্ট.বিল্ড.কমস্ট্রাকশন নেমস্পেসে একটি সলিউশনপার্সার ক্লাস রয়েছে যা ভিজ্যুয়াল স্টুডিও সমাধান ফাইলগুলি পার্স করে।

দুর্ভাগ্যক্রমে এই শ্রেণিটি অভ্যন্তরীণ, তবে আমি সেই কার্যকারিতাটির একটি অংশ এমন একটি ক্লাসে আবৃত করেছি যা আপনাকে সহায়ক মনে হতে পারে এমন কয়েকটি সাধারণ বৈশিষ্ট্য পেতে প্রতিফলন ব্যবহার করে।

public class Solution
{
    //internal class SolutionParser
    //Name: Microsoft.Build.Construction.SolutionParser
    //Assembly: Microsoft.Build, Version=4.0.0.0

    static readonly Type s_SolutionParser;
    static readonly PropertyInfo s_SolutionParser_solutionReader;
    static readonly MethodInfo s_SolutionParser_parseSolution;
    static readonly PropertyInfo s_SolutionParser_projects;

    static Solution()
    {
        s_SolutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
        if (s_SolutionParser != null)
        {
            s_SolutionParser_solutionReader = s_SolutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_projects = s_SolutionParser.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_parseSolution = s_SolutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);
        }
    }

    public List<SolutionProject> Projects { get; private set; }

    public Solution(string solutionFileName)
    {
        if (s_SolutionParser == null)
        {
            throw new InvalidOperationException("Can not find type 'Microsoft.Build.Construction.SolutionParser' are you missing a assembly reference to 'Microsoft.Build.dll'?");
        }
        var solutionParser = s_SolutionParser.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(null);
        using (var streamReader = new StreamReader(solutionFileName))
        {
            s_SolutionParser_solutionReader.SetValue(solutionParser, streamReader, null);
            s_SolutionParser_parseSolution.Invoke(solutionParser, null);
        }
        var projects = new List<SolutionProject>();
        var array = (Array)s_SolutionParser_projects.GetValue(solutionParser, null);
        for (int i = 0; i < array.Length; i++)
        {
            projects.Add(new SolutionProject(array.GetValue(i)));
        }
        this.Projects = projects;
    }
}

[DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
public class SolutionProject
{
    static readonly Type s_ProjectInSolution;
    static readonly PropertyInfo s_ProjectInSolution_ProjectName;
    static readonly PropertyInfo s_ProjectInSolution_RelativePath;
    static readonly PropertyInfo s_ProjectInSolution_ProjectGuid;
    static readonly PropertyInfo s_ProjectInSolution_ProjectType;

    static SolutionProject()
    {
        s_ProjectInSolution = Type.GetType("Microsoft.Build.Construction.ProjectInSolution, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
        if (s_ProjectInSolution != null)
        {
            s_ProjectInSolution_ProjectName = s_ProjectInSolution.GetProperty("ProjectName", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_RelativePath = s_ProjectInSolution.GetProperty("RelativePath", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_ProjectGuid = s_ProjectInSolution.GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_ProjectType = s_ProjectInSolution.GetProperty("ProjectType", BindingFlags.NonPublic | BindingFlags.Instance);
        }
    }

    public string ProjectName { get; private set; }
    public string RelativePath { get; private set; }
    public string ProjectGuid { get; private set; }
    public string ProjectType { get; private set; }

    public SolutionProject(object solutionProject)
    {
        this.ProjectName = s_ProjectInSolution_ProjectName.GetValue(solutionProject, null) as string;
        this.RelativePath = s_ProjectInSolution_RelativePath.GetValue(solutionProject, null) as string;
        this.ProjectGuid = s_ProjectInSolution_ProjectGuid.GetValue(solutionProject, null) as string;
        this.ProjectType = s_ProjectInSolution_ProjectType.GetValue(solutionProject, null).ToString();
    }
}

নোট করুন যে আপনাকে আপনার টার্গেট ফ্রেমওয়ার্কটি "। নেট ফ্রেমওয়ার্ক 4" (ক্লায়েন্ট প্রোফাইল নয়) এ মাইক্রোসফ্ট যুক্ত করতে সক্ষম হতে হবে।


3
এটি ঠিক আছে, তবে এটি "সমাধান আইটেম" গোষ্ঠীগুলিকে "প্রকল্পগুলি" হিসাবে দেখায় যা ভুল।
ডগ

3
এখানে যুক্ত করার জন্য "ব্যবহার" বিবৃতি রয়েছে: সিস্টেম ব্যবহার করে; সিস্টেম.রিফ্লেশন ব্যবহার করে; সিস্টেম.কলেশন.জেনারিক ব্যবহার করে; System.Diagnostics ব্যবহার করে; System.IO ব্যবহার করে; System.Linq ব্যবহার করে;
নিলওয়াল্টার্স

1
@ কিউকিনেট - আপনি অন্য সম্পত্তি যেমন প্রকাশিত হয়েছে তেমন একইভাবে s_প্রজেক্টইনসোলিউশন অবজেক্টের "প্রজেক্টটাইপ" সম্পত্তিটি পরীক্ষা করতে পারেন। এটি একটি এনাম ফেরত দেয় তবে কেবল এটি স্ট্রিং () করে। আমি এটিকে দুবার অন্তর্ভুক্ত করার জন্য পোস্টটি সম্পাদনা করার চেষ্টা করেছি তবে প্রতিবার শিখার মধ্যে পড়েছিলাম।
oasten

3
@ ওস্টেন ভাল উদ্দেশ্যগুলির মধ্যে যেমন সম্প্রদায়ের এই জাতীয় সম্পাদনাগুলি ডেকে আনা হয়েছে আপনি যদি এই বিষয়ে আরও জানতে চান তবে আপনার উচিত মেটা আলোচনায় জড়িত। আমি ব্যক্তিগতভাবে দেখতে পাই যে এটি কখনও কখনও কিছুটা ক্রেজি। দয়া করে মনে রাখবেন যে আপনার সম্পাদনাগুলি বন্ধ হয়ে যাওয়ার সাথে আমার কোনও সম্পর্ক ছিল না। যদিও আপনাকে আমি সম্পাদনাগুলি যুক্ত করার জন্য মনে করি সঠিক উপায়টি হ'ল আসলে অন্য উত্তর হিসাবে সমস্ত কিছু পোস্ট করা। এইভাবে এটি পরিষ্কার যে আমি মূলত সরবরাহ করেছিলাম তার শীর্ষে আপনি অবদানকারী। এটি বোধগম্য হয় তবে সংযোজন সরঞ্জামগুলি সত্যই একটি ভাল প্রতিক্রিয়া প্রক্রিয়া সরবরাহ করে না।
জন লিডেগ্রেন

18
একটি নতুন পাবলিক ক্লাস এর SolutionFileMicrosoft.Build.dll চালু যে ভিসুয়াল স্টুডিও 2015 সঙ্গে ইনস্টল (দেখুন msdn.microsoft.com/en-us/library/... )
ফিল

70

ভিজ্যুয়াল স্টুডিও 2015 এর সাথে এখন একটি সর্বজনীনভাবে অ্যাক্সেসযোগ্য SolutionFileশ্রেণি রয়েছে যা সমাধান ফাইলগুলি পার্স করতে ব্যবহার করা যেতে পারে:

using Microsoft.Build.Construction;
var _solutionFile = SolutionFile.Parse(path);

এই শ্রেণীটি মাইক্রোসফ্ট.বিল্ড.ডিল 14.0.0.0 অ্যাসেমব্লিতে পাওয়া যায় । আমার ক্ষেত্রে এটি অবস্থিত ছিল:

C:\Program Files (x86)\Reference Assemblies\Microsoft\MSBuild\v14.0\Microsoft.Build.dll

ধন্যবাদ ফিল জন্য এই ইশারা !


1
খুব দরকারী ... এটি আমি পাওয়ারশেল সেবনের জন্য ব্যবহার করেছি ...Add-Type -Path "C:\Program Files (x86)\Reference Assemblies\Microsoft\MSBuild\v14.0\Microsoft.Build.dll" $slnFile = [Microsoft.Build.Construction.SolutionFile]::Parse($slnPath); $slnFile.ProjectsInOrder
স্লিভারনিজা - এমএসএফটি

2
মাইক্রোসফ্ট.বিল্ড.ডিল ভিএইচ.০.০.০ এ ভিজ্যুয়াল স্টুডিও 2017 এর সাথে প্রেরণ করাতে আমি এই জাতীয় শ্রেণিটি খুঁজে পাইনি
জেফ জি

@ জেফজি একা মিসবিল্ড ইনস্টল করার চেষ্টা করুন।
ম্যাকিয়েজ কুচিয়া

1
@ জেফজি আমি ভিএস 2017 ব্যবহার করছি I যাইহোক, আমি যদি উপরের ফোল্ডারে অবস্থিত dll ব্রাউজ করে উল্লেখ করি তবে এটি কাজ করে বলে মনে হচ্ছে না।
Inrego

3
@ জেফজি এই প্যাকেজটি এখন নুগেট নুগেট.আর
রবার্ট হার্ডি

16

আমি জানি না যে কেউ এখনও এই সমস্যার সমাধান খুঁজছেন কিনা, তবে আমি এমন একটি প্রকল্প জুড়ে ছুটে এসেছি যা দেখে মনে হয় ঠিক যা করা দরকার do https://slntools.codeplex.com/ এই সরঞ্জামটির অন্যতম কাজ হ'ল একাধিক সমাধান একসাথে মার্জ করা।


সমাধান করা ফাইলটিতে আমি পরীক্ষিত হয়েছি, এই স্লানটুলগুলি রিশার্পার লাইবগুলির চেয়ে আসলে আরও বিশদ দিয়েছে।
রেজওয়ান ফ্ল্যাভিয়াস পান্ডা

14

জেটব্রেইনস ( রিশার্পারের স্রষ্টা) তাদের সমাবেশগুলিতে পাবলিক স্লান পার্সিংয়ের ক্ষমতা রাখে (কোনও প্রতিবিম্বের প্রয়োজন হয় না)। এটি এখানে প্রস্তাবিত বিদ্যমান ওপেন সোর্স সমাধানগুলির চেয়ে সম্ভবত আরও শক্তিশালী (রেজিেক্স হ্যাকগুলি ছেড়ে দেওয়া যাক)। আপনাকে যা করতে হবে তা হ'ল:

গ্রন্থাগারটি নথিভুক্ত নয়, তবে প্রতিচ্ছবিটি (বা সত্যই, ডটপিক) আপনার বন্ধু। উদাহরণ স্বরূপ:

public static void PrintProjects(string solutionPath)
{
    var slnFile = SolutionFileParser.ParseFile(FileSystemPath.Parse(solutionPath));
    foreach (var project in slnFile.Projects)
    {
        Console.WriteLine(project.ProjectName);
        Console.WriteLine(project.ProjectGuid);
        Console.WriteLine(project.ProjectTypeGuid);
        foreach (var kvp in project.ProjectSections)
        {
            Console.WriteLine(kvp.Key);
            foreach (var projectSection in kvp.Value) 
            {
                Console.WriteLine(projectSection.SectionName);
                Console.WriteLine(projectSection.SectionValue);
                foreach (var kvpp in projectSection.Properties)
                {
                    Console.WriteLine(kvpp.Key); 
                    Console.WriteLine(string.Join(",", kvpp.Value));
                }
            }
        }
    }
}

4
দ্রষ্টব্য: এই পোস্টের হিসাবে নাম স্থানগুলি কিছুটা আলাদা [সম্ভবত জেবি তাদের জিনিসগুলি পুনঃসেট করেছে :)]: et জেটব্রেইনস.প্ল্যাটফর্ম.প্রজেক্টমোডেল ~ জেটব্রেইনস.প্ল্যাটফর্ম.আইনটারপ.উইনপি
লিভিসনোর্ট

9

আমি আপনাকে সত্যিই একটি গ্রন্থাগার দিতে পারি না এবং আমার অনুমান যে সেখানে বিদ্যমান কোনও নেই। তবে আমি ব্যাচ সম্পাদনা করার পরিস্থিতিতে .sln ফাইলগুলির সাথে জগাখিচিতে সময় কাটিয়েছি এবং আমি পাওয়ারশেলকে এই কাজের জন্য একটি খুব দরকারী সরঞ্জাম হিসাবে পেয়েছি। .SLN ফর্ম্যাটটি বেশ সহজ এবং কয়েকটি দ্রুত এবং নোংরা এক্সপ্রেশন দিয়ে প্রায় পুরোপুরি পার্স করা যায়। উদাহরণ স্বরূপ

অন্তর্ভুক্ত প্রকল্প ফাইল।

gc ConsoleApplication30.sln | 
  ? { $_ -match "^Project" } | 
  %{ $_ -match ".*=(.*)$" | out-null ; $matches[1] } | 
  %{ $_.Split(",")[1].Trim().Trim('"') }

এটি সর্বদা সুন্দর নয়, তবে এটি ব্যাচ প্রসেসিংয়ের কার্যকর উপায়।


হ্যাঁ,
এতোদিন

সমাধান ফোল্ডারগুলি বাদ দেওয়ার জন্য এটি আমার জন্য কাজ করে: (গেট-কনটেন্ট মাই সলিউশন.স্লেন) | কোথায়-অবজেক্ট {$ _-ম্যাচ '(? = ^ প্রকল্প (?! \ ("\ {2150E333-8FDC-42A3-9474-1A3956D46DE8 \}" \))) ^ (\ ডাব্লু +)'} | ফরইচ-অবজেক্ট {$ _-ম্যাচ "। * = (। *) $" | আউট-নাল; $ ম্যাচগুলি [1]} | ফরইচ-অবজেক্ট {$ _। স্প্লিট (",") [1]। ট্রিম ()। ট্রিম ('' ')}
ডেভিড গার্ডিনার

6

আমরা ভিজ্যুয়াল স্টুডিও প্লাগইন লিখে স্বয়ংক্রিয়ভাবে সমাধানগুলি মার্জ করার একই ধরণের সমস্যা সমাধান করেছি যা একটি নতুন সমাধান তৈরি করে তারপরে * .sln ফাইল অনুসন্ধান করে এবং এগুলি ব্যবহার করে নতুনটিতে আমদানি করে:

dte2.Solution.AddFromFile(solutionPath, false);

আমাদের সমস্যাটি কিছুটা আলাদা ছিল কারণ আমরা চেয়েছিলাম যে ভিএস আমাদের জন্য বিল্ড অর্ডারটি বাছাই করুক, সুতরাং আমরা যে কোনও ডিএল রেফারেন্সকে যেখানে সম্ভব সেখানে প্রকল্পের রেফারেন্সে রূপান্তরিত করেছিলাম।

এরপরে আমরা এটিকে COM অটোমেশনের মাধ্যমে ভিএস চালিয়ে একটি বিল্ড প্রক্রিয়াতে স্বয়ংক্রিয়ভাবে তৈরি করেছি।

এই সমাধানটি একটু হিথ রবিনসন ছিল, তবে সুবিধা ছিল যে ভিএস সম্পাদনা করছে তাই আমাদের কোডটি স্লান ফাইলের ফর্ম্যাটের উপর নির্ভর করে না। যা ভিএস ২০০৫ থেকে ২০০৮ এবং আবার ২০১০ এ চলে এসেছিল যা সহায়ক ছিল।


ডিটিই ব্যবহার করে আপনার পারফরম্যান্সে সমস্যা আছে এবং যদি তাই হয় তবে কীভাবে আপনি এটি সমাধান করেছেন? stackoverflow.com/questions/1620199/...
ক্রিস Moutray

@ মাউটাররা আমরা দেখতে পেয়েছি যে ডিটিই ব্যবহার করে এবং গুই ব্যবহার করা প্রায় একই পারফরম্যান্স অনুযায়ী ছিল। কেবলমাত্র ন্যূনতম ভিএস বিকল্পগুলি ইনস্টল করা কিছুটা সহায়তা করেছে, তবে খুব বেশি নয়। যেহেতু এটি স্বয়ংক্রিয়ভাবে এবং রাতারাতি চলছে, পারফরম্যান্স এমন কিছু নয় যা আমরা উদ্বিগ্ন হয়েছি।
অ্যান্ডি লোরি

যদি স্লেনের ফোল্ডারটিতে প্রকল্প অন্তর্ভুক্ত থাকে তবে আপনি যে প্রকল্পটি ফোল্ডারে অন্তর্ভুক্ত করতে পারবেন তা করতে পারবেন না।
lindexi

5

সবকিছু দুর্দান্ত, তবে আমি স্লোন প্রজন্মের সক্ষমতা অর্জন করতেও চেয়েছিলাম - উপরে কোড স্ন্যাপশটে আপনি কেবল .sln ফাইলগুলি পার্স করছেন - .ll ফাইলটিতে ফিরে সামান্য পরিবর্তন সহ স্লেন পুনরায় উত্পন্ন করতে সক্ষম হওয়া ছাড়া আমি একই জিনিস তৈরি করতে চেয়েছিলাম s । এই জাতীয় ক্ষেত্রে বিভিন্ন। নেট প্ল্যাটফর্মের জন্য একই প্রকল্পের পোর্টিং উদাহরণস্বরূপ হতে পারে। আপাতত এটি কেবল স্লান পুনরায় প্রজন্মের, তবে পরে আমি এটি প্রকল্পগুলিতেও প্রসারিত করব।

আমি অনুমান করি যে আমি নিয়মিত অভিব্যক্তি এবং নেটিভ ইন্টারফেসের শক্তিও প্রদর্শন করতে চেয়েছিলাম। (আরও কার্যকারিতা সহ কোডের ক্ষুদ্র পরিমাণ)

আপডেট 4.1.2017 আমি .sln সমাধান পার্স জন্য পৃথক SVN সংগ্রহস্থলের তৈরি করেছি: https://sourceforge.net/p/syncproj/code/HEAD/tree/

নীচে আমার নিজস্ব কোড নমুনা স্নিপেট (পূর্বসূরী) রয়েছে। আপনি এগুলির যে কোনওটি ব্যবহার করতে নির্দ্বিধায়।

এটি সম্ভব যে ভবিষ্যতে এসএনএন ভিত্তিক সমাধান পার্সিং কোডও প্রজন্মের ক্ষমতা সহ আপডেট হবে।

আপডেট 4.2.2017 এসভিএন- তে উত্স কোডটি .sln প্রজন্মকেও সমর্থন করছে।

using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Text;


public class Program
{
    [DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
    public class SolutionProject
    {
        public string ParentProjectGuid;
        public string ProjectName;
        public string RelativePath;
        public string ProjectGuid;

        public string AsSlnString()
        { 
            return "Project(\"" + ParentProjectGuid + "\") = \"" + ProjectName + "\", \"" + RelativePath + "\", \"" + ProjectGuid + "\"";
        }
    }

/// <summary>
/// .sln loaded into class.
/// </summary>
public class Solution
{
    public List<object> slnLines;       // List of either String (line format is not intresting to us), or SolutionProject.

    /// <summary>
    /// Loads visual studio .sln solution
    /// </summary>
    /// <param name="solutionFileName"></param>
    /// <exception cref="System.IO.FileNotFoundException">The file specified in path was not found.</exception>
    public Solution( string solutionFileName )
    {
        slnLines = new List<object>();
        String slnTxt = File.ReadAllText(solutionFileName);
        string[] lines = slnTxt.Split('\n');
        //Match string like: Project("{66666666-7777-8888-9999-AAAAAAAAAAAA}") = "ProjectName", "projectpath.csproj", "{11111111-2222-3333-4444-555555555555}"
        Regex projMatcher = new Regex("Project\\(\"(?<ParentProjectGuid>{[A-F0-9-]+})\"\\) = \"(?<ProjectName>.*?)\", \"(?<RelativePath>.*?)\", \"(?<ProjectGuid>{[A-F0-9-]+})");

        Regex.Replace(slnTxt, "^(.*?)[\n\r]*$", new MatchEvaluator(m =>
            {
                String line = m.Groups[1].Value;

                Match m2 = projMatcher.Match(line);
                if (m2.Groups.Count < 2)
                {
                    slnLines.Add(line);
                    return "";
                }

                SolutionProject s = new SolutionProject();
                foreach (String g in projMatcher.GetGroupNames().Where(x => x != "0")) /* "0" - RegEx special kind of group */
                    s.GetType().GetField(g).SetValue(s, m2.Groups[g].ToString());

                slnLines.Add(s);
                return "";
            }), 
            RegexOptions.Multiline
        );
    }

    /// <summary>
    /// Gets list of sub-projects in solution.
    /// </summary>
    /// <param name="bGetAlsoFolders">true if get also sub-folders.</param>
    public List<SolutionProject> GetProjects( bool bGetAlsoFolders = false )
    {
        var q = slnLines.Where( x => x is SolutionProject ).Select( i => i as SolutionProject );

        if( !bGetAlsoFolders )  // Filter away folder names in solution.
            q = q.Where( x => x.RelativePath != x.ProjectName );

        return q.ToList();
    }

    /// <summary>
    /// Saves solution as file.
    /// </summary>
    public void SaveAs( String asFilename )
    {
        StringBuilder s = new StringBuilder();

        for( int i = 0; i < slnLines.Count; i++ )
        {
            if( slnLines[i] is String ) 
                s.Append(slnLines[i]);
            else
                s.Append((slnLines[i] as SolutionProject).AsSlnString() );

            if( i != slnLines.Count )
                s.AppendLine();
        }

        File.WriteAllText(asFilename, s.ToString());
    }
}


    static void Main()
    {
        String projectFile = @"yourown.sln";

        try
        {
            String outProjectFile = Path.Combine(Path.GetDirectoryName(projectFile), Path.GetFileNameWithoutExtension(projectFile) + "_2.sln");
            Solution s = new Solution(projectFile);
            foreach( var proj in s.GetProjects() )
            {
                Console.WriteLine( proj.RelativePath );
            }

            SolutionProject p = s.GetProjects().Where( x => x.ProjectName.Contains("Plugin") ).First();
            p.RelativePath = Path.Combine( Path.GetDirectoryName(p.RelativePath) , Path.GetFileNameWithoutExtension(p.RelativePath) + "_Variation" + ".csproj");

            s.SaveAs(outProjectFile);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }
}

3

আমি বিস্তৃত করেছি, নির্ধারিত করেছি যে এমএসবিল্ড ক্লাসগুলি অন্তর্নিহিত কাঠামোগত কৌশলগুলি ব্যবহার করতে ব্যবহার করা যেতে পারে। আমার ওয়েবসাইটে পরে আরও কোড থাকবে।

// VSSolution

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.IO;
using AbstractX.Contracts;

namespace VSProvider
{
    public class VSSolution : IVSSolution
    {
        //internal class SolutionParser 
        //Name: Microsoft.Build.Construction.SolutionParser 
        //Assembly: Microsoft.Build, Version=4.0.0.0 

        static readonly Type s_SolutionParser;
        static readonly PropertyInfo s_SolutionParser_solutionReader;
        static readonly MethodInfo s_SolutionParser_parseSolution;
        static readonly PropertyInfo s_SolutionParser_projects;
        private string solutionFileName;
        private List<VSProject> projects;

        public string Name
        {
            get
            {
                return Path.GetFileNameWithoutExtension(solutionFileName);
            }
        }

        public IEnumerable<IVSProject> Projects
        {
            get
            {
                return projects;
            }
        }

        static VSSolution()
        {
            s_SolutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
            s_SolutionParser_solutionReader = s_SolutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_projects = s_SolutionParser.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_parseSolution = s_SolutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);
        }

        public string SolutionPath
        {
            get
            {
                var file = new FileInfo(solutionFileName);

                return file.DirectoryName;
            }
        }

        public VSSolution(string solutionFileName)
        {
            if (s_SolutionParser == null)
            {
                throw new InvalidOperationException("Can not find type 'Microsoft.Build.Construction.SolutionParser' are you missing a assembly reference to 'Microsoft.Build.dll'?");
            }

            var solutionParser = s_SolutionParser.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(null);

            using (var streamReader = new StreamReader(solutionFileName))
            {
                s_SolutionParser_solutionReader.SetValue(solutionParser, streamReader, null);
                s_SolutionParser_parseSolution.Invoke(solutionParser, null);
            }

            this.solutionFileName = solutionFileName;

            projects = new List<VSProject>();
            var array = (Array)s_SolutionParser_projects.GetValue(solutionParser, null);

            for (int i = 0; i < array.Length; i++)
            {
                projects.Add(new VSProject(this, array.GetValue(i)));
            }
        }

        public void Dispose()
        {
        }
    }
}

// VSProject

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.IO;
using System.Xml;
using AbstractX.Contracts;
using System.Collections;

namespace VSProvider
{
    [DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
    public class VSProject : IVSProject
    {
        static readonly Type s_ProjectInSolution;
        static readonly Type s_RootElement;
        static readonly Type s_ProjectRootElement;
        static readonly Type s_ProjectRootElementCache;
        static readonly PropertyInfo s_ProjectInSolution_ProjectName;
        static readonly PropertyInfo s_ProjectInSolution_ProjectType;
        static readonly PropertyInfo s_ProjectInSolution_RelativePath;
        static readonly PropertyInfo s_ProjectInSolution_ProjectGuid;
        static readonly PropertyInfo s_ProjectRootElement_Items;

        private VSSolution solution;
        private string projectFileName;
        private object internalSolutionProject;
        private List<VSProjectItem> items;
        public string Name { get; private set; }
        public string ProjectType { get; private set; }
        public string RelativePath { get; private set; }
        public string ProjectGuid { get; private set; }

        public string FileName
        {
            get
            {
                return projectFileName;
            }
        }

        static VSProject()
        {
            s_ProjectInSolution = Type.GetType("Microsoft.Build.Construction.ProjectInSolution, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);

            s_ProjectInSolution_ProjectName = s_ProjectInSolution.GetProperty("ProjectName", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_ProjectType = s_ProjectInSolution.GetProperty("ProjectType", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_RelativePath = s_ProjectInSolution.GetProperty("RelativePath", BindingFlags.NonPublic | BindingFlags.Instance);
            s_ProjectInSolution_ProjectGuid = s_ProjectInSolution.GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance);

            s_ProjectRootElement = Type.GetType("Microsoft.Build.Construction.ProjectRootElement, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
            s_ProjectRootElementCache = Type.GetType("Microsoft.Build.Evaluation.ProjectRootElementCache, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);

            s_ProjectRootElement_Items = s_ProjectRootElement.GetProperty("Items", BindingFlags.Public | BindingFlags.Instance);
        }

        public IEnumerable<IVSProjectItem> Items
        {
            get
            {
                return items;
            }
        }

        public VSProject(VSSolution solution, object internalSolutionProject)
        {
            this.Name = s_ProjectInSolution_ProjectName.GetValue(internalSolutionProject, null) as string;
            this.ProjectType = s_ProjectInSolution_ProjectType.GetValue(internalSolutionProject, null).ToString();
            this.RelativePath = s_ProjectInSolution_RelativePath.GetValue(internalSolutionProject, null) as string;
            this.ProjectGuid = s_ProjectInSolution_ProjectGuid.GetValue(internalSolutionProject, null) as string;

            this.solution = solution;
            this.internalSolutionProject = internalSolutionProject;

            this.projectFileName = Path.Combine(solution.SolutionPath, this.RelativePath);

            items = new List<VSProjectItem>();

            if (this.ProjectType == "KnownToBeMSBuildFormat")
            {
                this.Parse();
            }
        }

        private void Parse()
        {
            var stream = File.OpenRead(projectFileName);
            var reader = XmlReader.Create(stream);
            var cache = s_ProjectRootElementCache.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(new object[] { true });
            var rootElement = s_ProjectRootElement.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(new object[] { reader, cache });

            stream.Close();

            var collection = (ICollection)s_ProjectRootElement_Items.GetValue(rootElement, null);

            foreach (var item in collection)
            {
                items.Add(new VSProjectItem(this, item));
            }

        }

        public IEnumerable<IVSProjectItem> EDMXModels
        {
            get 
            {
                return this.items.Where(i => i.ItemType == "EntityDeploy");
            }
        }

        public void Dispose()
        {
        }
    }
}

// VSProjectItem

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.IO;
using System.Xml;
using AbstractX.Contracts;

namespace VSProvider
{
    [DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
    public class VSProjectItem : IVSProjectItem
    {
        static readonly Type s_ProjectItemElement;
        static readonly PropertyInfo s_ProjectItemElement_ItemType;
        static readonly PropertyInfo s_ProjectItemElement_Include;

        private VSProject project;
        private object internalProjectItem;
        private string fileName;

        static VSProjectItem()
        {
            s_ProjectItemElement = Type.GetType("Microsoft.Build.Construction.ProjectItemElement, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);

            s_ProjectItemElement_ItemType = s_ProjectItemElement.GetProperty("ItemType", BindingFlags.Public | BindingFlags.Instance);
            s_ProjectItemElement_Include = s_ProjectItemElement.GetProperty("Include", BindingFlags.Public | BindingFlags.Instance);
        }

        public string ItemType { get; private set; }
        public string Include { get; private set; }

        public VSProjectItem(VSProject project, object internalProjectItem)
        {
            this.ItemType = s_ProjectItemElement_ItemType.GetValue(internalProjectItem, null) as string;
            this.Include = s_ProjectItemElement_Include.GetValue(internalProjectItem, null) as string;
            this.project = project;
            this.internalProjectItem = internalProjectItem;

            // todo - expand this

            if (this.ItemType == "Compile" || this.ItemType == "EntityDeploy")
            {
                var file = new FileInfo(project.FileName);

                fileName = Path.Combine(file.DirectoryName, this.Include);
            }
        }

        public byte[] FileContents
        {
            get 
            {
                return File.ReadAllBytes(fileName);
            }
        }

        public string Name
        {
            get 
            {
                if (fileName != null)
                {
                    var file = new FileInfo(fileName);

                    return file.Name;
                }
                else
                {
                    return this.Include;
                }
            }
        }
    }
}

অ্যাবস্ট্রাকএক্স কোথা থেকে এসেছে এমন কোনও ধারণা?
gunr2171

এটি এএসপি. নেট ওয়েবসাইটগুলির ভুল ব্যাখ্যা করে বলে মনে হচ্ছে যেখানে সাইটগুলিrelativepath ইউএসএল এক্সপ্রেস ইত্যাদির আওতায় চলতে হবে এমন ইউআরএল হয়ে যায়।
ডগ

1

@ জন-লেডেগ্রেনের উত্তর দুর্দান্ত। প্রাক VS2015 এর জন্য, এটি দুর্দান্ত ব্যবহার। কনফিগারেশন পুনরুদ্ধার করার কোডটি অনুপস্থিত হওয়ায় একটি ছোট্ট ভুল ছিল। সুতরাং এটি যুক্ত করতে চেয়েছিলেন, যদি কেউ এই কোডটি ব্যবহার করার জন্য লড়াই করছে।
বর্ধন খুব সহজ:

    public class Solution
{
    //internal class SolutionParser
    //Name: Microsoft.Build.Construction.SolutionParser
    //Assembly: Microsoft.Build, Version=4.0.0.0

    static readonly Type s_SolutionParser;
    static readonly PropertyInfo s_SolutionParser_solutionReader;
    static readonly MethodInfo s_SolutionParser_parseSolution;
    static readonly PropertyInfo s_SolutionParser_projects;
    static readonly PropertyInfo s_SolutionParser_configurations;//this was missing in john's answer


    static Solution()
    {
        s_SolutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
        if ( s_SolutionParser != null )
        {
            s_SolutionParser_solutionReader = s_SolutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_projects = s_SolutionParser.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_parseSolution = s_SolutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);
            s_SolutionParser_configurations = s_SolutionParser.GetProperty("SolutionConfigurations", BindingFlags.NonPublic | BindingFlags.Instance); //this was missing in john's answer

            // additional info:
            var PropNameLst = GenHlp_PropBrowser.PropNamesOfType(s_SolutionParser);
            // the above call would yield something like this:
            // [ 0] "SolutionParserWarnings"        string
            // [ 1] "SolutionParserComments"        string
            // [ 2] "SolutionParserErrorCodes"      string
            // [ 3] "Version"                       string
            // [ 4] "ContainsWebProjects"           string
            // [ 5] "ContainsWebDeploymentProjects" string
            // [ 6] "ProjectsInOrder"               string
            // [ 7] "ProjectsByGuid"                string
            // [ 8] "SolutionFile"                  string
            // [ 9] "SolutionFileDirectory"         string
            // [10] "SolutionReader"                string
            // [11] "Projects"                      string
            // [12] "SolutionConfigurations"        string
        }
    }

    public List<SolutionProject> Projects { get; private set; }
    public List<SolutionConfiguration> Configurations { get; private set; }

   //...
   //...
   //... no change in the rest of the code
}

অতিরিক্ত সহায়তা হিসাবে, System.Type@ ওস্টেনের পরামর্শ অনুসারে কোনও বৈশিষ্ট্যের মধ্যে ব্রাউজ করার জন্য সহজ কোড সরবরাহ করা ।

public class GenHlp_PropBrowser
{
    public static List<string> PropNamesOfClass(object anObj)
    {
        return anObj == null ? null : PropNamesOfType(anObj.GetType());
    }
    public static List<String> PropNamesOfType(System.Type aTyp)
    {
        List<string> retLst = new List<string>();
        foreach ( var p in aTyp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance) )
        {
            retLst.Add(p.Name);
        }
        return retLst;
    }
}


0

ধন্যবাদ জন লাইডেগ্রেন তিনি কার্যকর উপায় উপস্থাপন করেছেন। আমি তার কোড ব্যবহার করতে পারি না এমন পোষাক ব্যবহার করতে পারি না তার জন্য আমি একটি এইচপি ক্লাস লিখিs_SolutionParser_configurations ব্যতীত এবং প্রকল্পগুলি ।

কোডটি গিথুবে রয়েছে যা পুরো নাম দিয়ে প্রকল্পগুলি পেতে পারে।

এবং কোডটি ক্যান্সারটি সলিউশনসিফিকেশন পায়।

তবে আপনি যখন একটি ভার্সিক্স দেবেন তখন বনাম বলবে না ক্যান্থ সন্ধান করুন Microsoft.Build.dll , সুতরাং আপনি সমস্ত প্রকল্পগুলি পেতে ডিটি ব্যবহার করতে পারেন।

কোডটি ব্যবহার DTE সমস্ত প্রকল্প পেতে হয় GitHub


@ এনপি 83 আপনাকে ধন্যবাদ এবং আমি লিঙ্কটি মুছে
ফেলেছি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.