0

Question 1: is the format of default solution file of c# ProjectText always same?

Project(Solution GUI) = SolutionName , ProjectPath, csProjPath, ProjectGUI

e.g:

Project("{FAE14EC0-321D-12D3-GF35-01C04F79EFBC}") = "WindowsFormsApplication26", "WindowsFormsApplication26\WindowsFormsApplication26.csproj", "{25F0453B-9C88-4C9E-AG6A-97873BB6EA23}"
EndProject

same format as: 1st it will have Solution GUI then solutionName then csproj path then projectGUI

Question 2: i have created a regex to get the Text generated by .sln and here's what i've got:

Regex projectRegex = new Regex(@"Project\(\""([^\""]+)\""\)\s*\=\s*\""([^\""]+)\""\,\s*\""([^\""]+)""\,\s*\""([^\""]+)""");

but im not sure if there's a possible bug in my regex related with the first question, so im thinking if theres a better regex or any condition (e.g parse or any that must be faster) to get the ProjectText specifically (what i need to get) was the csProj path (which is on regex pattern above on Group3)

and for the group applied on example shown on Q1:

Group1: {FAE14EC0-321D-12D3-GF35-01C04F79EFBC}
Group2: WindowsFormsApplication26
Group3: WindowsFormsApplication26\WindowsFormsApplication26.csproj
Group4: {25F0453B-9C88-4C9E-AG6A-97873BB6EA23}
Elegiac
  • 361
  • 2
  • 15

1 Answers1

0

I think your way should by working correctly but for extracting information from solution files we use the following method by accessing the internal technique of the 'Microsoft.Build' namespace. As the corresponding framework functions are marked as internal, it is necessary to 'hack' them. Therefore the complicated way using reflection. (It's a condensed extract from other code snippets we found in internet - also in SO)

public struct ProjectData
{
    public string Name;
    public string Guid;
    public string Path;
}

public static List<ProjectData> GetProjectsInSolution(string pathToSolutionFile)
{
    Type parserType = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);

    ConstructorInfo constructorInfo = parserType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();
    object solutionParser = constructorInfo.Invoke(null);

    PropertyInfo solutionFileProperty = parserType.GetProperty("SolutionFile", BindingFlags.NonPublic | BindingFlags.Instance);
    solutionFileProperty.SetValue(solutionParser, pathToSolutionFile);

    MethodInfo parserMethod = parserType.GetMethod("ParseSolutionFile", BindingFlags.NonPublic | BindingFlags.Instance);
    parserMethod.Invoke(solutionParser, null);

    PropertyInfo projectInfo = parserType.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] projects = projectInfo.GetValue(solutionParser) as object[];

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

    PropertyInfo nameInfo = projectType.GetProperty("ProjectName", BindingFlags.NonPublic | BindingFlags.Instance);
    PropertyInfo guidInfo = projectType.GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance);
    PropertyInfo pathInfo = projectType.GetProperty("RelativePath", BindingFlags.NonPublic | BindingFlags.Instance);

    List<ProjectData> projectData = new List<ProjectData>();

    if (projects != null)
    {
        foreach (object project in projects)
        {
            projectData.Add(new ProjectData()
            {
                Name = nameInfo.GetValue(project) as string,
                Guid = guidInfo.GetValue(project) as string,
                Path = pathInfo.GetValue(project) as string
            });
        }
    }

    return projectData;
}
Fratyx
  • 5,717
  • 1
  • 12
  • 22
  • how about for the solution GUI? – Elegiac Dec 08 '14 at 08:27
  • i guess the the version GUI wasnt the one appeared after Project(" ... but the 1st 3 info was correct ... – Elegiac Dec 08 '14 at 09:13
  • but its not the one that appeared after Project(" ... or it just regenerated? (or if not how can i get it?) ... anyways the answer works so if that part cant get by parser ill accept this answer ... – Elegiac Dec 08 '14 at 09:23
  • It should be the GUID for CS projects. You could set a breakpoint after creation of `solutionParser` object. In 'Watch' window inspect the static!! members of this object. Maybe one of the GUIDs you can find here is the one you are looking for. – Fratyx Dec 08 '14 at 09:30
  • ive tested it ... the Guid that was generated was the project GUI which is the GUI beside csProj, as i mention above in my question, but the version was not the one that im looking for but the GUID (correct me if im wrong) which is like this: Project("{FAE14EC0-321D-12D3-GF35-01C04F79EFBC}") – Elegiac Dec 08 '14 at 09:34
  • Sorry, you are right, the change I made was rubbish so I made a rollback. I really don't know at the moment how to get this GUID from the parser. I just found this [list](http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs). – Fratyx Dec 08 '14 at 10:04
  • still thanks a lot for the help ... ill try to map the Guid that i wanted – Elegiac Dec 08 '14 at 10:46