public static MSVSProjectFile FromFile(string filepath)
        {
            var ProjectFileName = new FileInfo(filepath);

            var Document = XDocument.Load(filepath);


            var HintPaths = Document.Root.Elements(nsItemGroup).Elements(nsReference).Elements(nsHintPath).Select(k => k.Value).ToArray();

            var DefaultNamespace = Enumerable.First(
                 from PropertyGroup in Document.Root.Elements(nsPropertyGroup)
                     //from RootNamespace in PropertyGroup.Elements(nsRootNamespace)
                     //select RootNamespace.Value

                 from __AssemblyName in PropertyGroup.Elements(nsAssemblyName)
                 select __AssemblyName.Value
            );


            // emulate $safeprojectname$
            DefaultNamespace = DefaultNamespace.Replace(" ", "_");

            #region GetFilesByType
            Func<XName, IEnumerable<ProjectFileInfo>> GetFilesByType =
                FileType =>
                      from ItemGroup in Document.Root.Elements(nsItemGroup)

                      from None in ItemGroup.Elements(FileType)

                          // <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
                      let Link0 = None.Element(nsLink)

                      // Include = "Y:\\opensource\\github\\elastic-droid\\src\\**\\*.*"
                      let Include0 = None.Attribute("Include").Value

                      // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20141127
                      // what about *.java ?
                      let Wildcard = @"**\*.*"
                      let IsWildcard = Include0.EndsWith(Wildcard)

                      let IncludeWildcard = Include0.TakeUntilLastOrNull(Wildcard)

                      let Include1 = !IsWildcard ?
                        new[] { Include0 } :
                        Directory.EnumerateFiles(IncludeWildcard, "*.*", SearchOption.AllDirectories)


                      from Include in Include1

                      let IncludeDirectory = Path.GetDirectoryName(Include)

                      let Replace = new
                      {
                          Extension = Path.GetExtension(Include),
                          FileName = Path.GetFileNameWithoutExtension(Include),
                          RecursiveDir = IncludeDirectory.SkipUntilOrEmpty(IncludeWildcard),
                      }

                      //let Include = Include0
                      let Link = Link0 == null ? null : new
                      {
                          Value =
                              Link0.Value
                              .Replace("%(Extension)", Replace.Extension)
                              .Replace("%(FileName)", Replace.FileName)
                              .Replace("%(RecursiveDir)", Replace.RecursiveDir == "" ? "" : Replace.RecursiveDir + "\\")
                      }

                      // Directory In Project
                      let Directory = Path.GetDirectoryName(Link != null ? Link.Value : Include).Replace("\\", "/")

                      let File = new FileInfo(
                          Link != null ?
                          Include :
                          Path.Combine(ProjectFileName.Directory.FullName, Include)
                          )

                      select new ProjectFileInfo { File = File, NamespaceDirectory = Directory };
            #endregion





            #region HasReference
            Func<FileInfo, bool> HasReference =
              AssemblyFile =>
              {
                  // z:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\Studio\MSVSProjectFile.cs
                  // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150907/glsl
                  var TargetHintPath = GetRelativePathOrNull(
                      ProjectFileName.Directory.FullName,
                      AssemblyFile.FullName
                      ) ?? AssemblyFile.FullName;


                  return Enumerable.Any(
                       from ItemGroup in Document.Root.Elements(nsItemGroup)
                       from Reference in ItemGroup.Elements(nsReference)
                       from HintPath in Reference.Elements(nsHintPath)
                       where TargetHintPath == HintPath.Value
                       select new { HintPath, Reference, ItemGroup }
                  );
              };
            #endregion

            #region GetAssemblyReferences
            Func<FileInfo[]> GetAssemblyReferences =
               delegate
               {
                   var a =
                       from ItemGroup in Document.Root.Elements(nsItemGroup)
                       from Reference in ItemGroup.Elements(nsReference)
                       from HintPath in Reference.Elements(nsHintPath)
                       let AssemblyReferencePath = Path.Combine(new FileInfo(filepath).Directory.FullName, HintPath.Value)
                       select new FileInfo(AssemblyReferencePath);


                   //            <Reference Include="My.Solutions.Pages.OpCode.AssetsLibrary">
                   //  <HintPath>bin\staging.AssetsLibrary\My.Solutions.Pages.OpCode.AssetsLibrary.dll</HintPath>
                   //</Reference>

                   return a.ToArray();

               };
            #endregion

            #region GetProjectReferences
            Func<MSVSProjectFile[]> GetProjectReferences =
                delegate
                {
                    var a =
                       from ItemGroup in Document.Root.Elements(nsItemGroup)
                       from ProjectReference in ItemGroup.Elements(nsProjectReference)
                       let Include = ProjectReference.Attribute("Include")
                       let ProjectReferencePath = Path.Combine(new FileInfo(filepath).Directory.FullName, Include.Value)
                       where File.Exists(ProjectReferencePath)
                       select (MSVSProjectFile)new FileInfo(ProjectReferencePath);

                    //<ItemGroup>
                    //  <ProjectReference Include="..\..\My.Solutions.Pages.OpCode\My.Solutions.Pages.OpCode\My.Solutions.Pages.OpCode.csproj">
                    //    <Project>{5823d538-ea39-4d2a-9c15-f3bce76c9781}</Project>
                    //    <Name>My.Solutions.Pages.OpCode</Name>
                    //  </ProjectReference>



                    return a.ToArray();
                };
            #endregion


            MSVSProjectFile __this = null;

            #region AddReference
            Action<FileInfo, AssemblyName> AddReference =
                (AssemblyFile, Name) =>
                {
                    // z:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\Studio\MSVSProjectFile.cs
                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150907/glsl


                    Console.WriteLine("AddReference GetRelativePathOrNull " + new { AssemblyFile, Name });


                    /* add reference
<Reference Include="AutoGeneratedReferences.Components.JohDoe.TextComponent, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>bin\staging\AutoGeneratedReferences.Components.JohDoe.TextComponent.dll</HintPath>
</Reference>
                    */

                    if (!AssemblyFile.Exists)
                        return;

                    //var TargetHintPath = AssemblyFile.FullName.Substring(ProjectFileName.Directory.FullName.Length + 1);
                    var TargetHintPath = GetRelativePathOrNull(
                        ProjectFileName.Directory.FullName,
                        AssemblyFile.FullName
                        ) ?? AssemblyFile.FullName;




                    // sanity check
                    if (!HasReference(AssemblyFile))
                    {
                        var TargetItemGroup = Enumerable.First(
                            from ItemGroup in Document.Root.Elements(nsItemGroup)
                            from Reference in ItemGroup.Elements(nsReference)
                            select ItemGroup
                        );

                        Console.WriteLine("AddReference " + new { TargetHintPath });

                        TargetItemGroup.Add(
                            new XElement(nsReference,
                                new XAttribute("Include", Name.ToString()),
                                new XElement(nsHintPath, TargetHintPath)
                            )
                        );

                        __this.RaiseReferenceAdded();
                    }
                };
            #endregion

            Action Save = delegate
            {
                Document.Save(filepath);
            };

            return __this = new MSVSProjectFile
            {
                Document = Document,

                HintPaths = HintPaths,
                DefaultNamespace = DefaultNamespace,
                NoneFiles = GetFilesByType(nsNone).ToArray(),
                ContentFiles = GetFilesByType(nsContent).ToArray(),
                HasReference = HasReference,
                AddReference = AddReference,
                Save = Save,
                GetProjectReferences = GetProjectReferences,
                GetAssemblyReferences = GetAssemblyReferences
            };
        }
Example #2
0
        public static MSVSProjectFile FromFile(string filepath)
        {
            var ProjectFileName = new FileInfo(filepath);

            var Document = XDocument.Load(filepath);


            var HintPaths = Document.Root.Elements(nsItemGroup).Elements(nsReference).Elements(nsHintPath).Select(k => k.Value).ToArray();

            var DefaultNamespace = Enumerable.First(
                from PropertyGroup in Document.Root.Elements(nsPropertyGroup)
                //from RootNamespace in PropertyGroup.Elements(nsRootNamespace)
                //select RootNamespace.Value

                from __AssemblyName in PropertyGroup.Elements(nsAssemblyName)
                select __AssemblyName.Value
                );


            // emulate $safeprojectname$
            DefaultNamespace = DefaultNamespace.Replace(" ", "_");

            #region GetFilesByType
            Func <XName, IEnumerable <ProjectFileInfo> > GetFilesByType =
                FileType =>
                from ItemGroup in Document.Root.Elements(nsItemGroup)

                from None in ItemGroup.Elements(FileType)

                // <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
                let Link0 = None.Element(nsLink)

                            // Include = "Y:\\opensource\\github\\elastic-droid\\src\\**\\*.*"
                            let Include0 = None.Attribute("Include").Value

                                           // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20141127
                                           // what about *.java ?
                                           let Wildcard = @"**\*.*"
                                                          let IsWildcard = Include0.EndsWith(Wildcard)

                                                                           let IncludeWildcard = Include0.TakeUntilLastOrNull(Wildcard)

                                                                                                 let Include1 = !IsWildcard ?
                                                                                                                new[] { Include0 } :
            Directory.EnumerateFiles(IncludeWildcard, "*.*", SearchOption.AllDirectories)


            from Include in Include1

            let IncludeDirectory = Path.GetDirectoryName(Include)

                                   let Replace = new
            {
                Extension    = Path.GetExtension(Include),
                FileName     = Path.GetFileNameWithoutExtension(Include),
                RecursiveDir = IncludeDirectory.SkipUntilOrEmpty(IncludeWildcard),
            }

            //let Include = Include0
            let Link = Link0 == null ? null : new
            {
                Value =
                    Link0.Value
                    .Replace("%(Extension)", Replace.Extension)
                    .Replace("%(FileName)", Replace.FileName)
                    .Replace("%(RecursiveDir)", Replace.RecursiveDir == "" ? "" : Replace.RecursiveDir + "\\")
            }

            // Directory In Project
            let Directory = Path.GetDirectoryName(Link != null ? Link.Value : Include).Replace("\\", "/")

                            let File = new FileInfo(
                Link != null ?
                Include :
                Path.Combine(ProjectFileName.Directory.FullName, Include)
                )

                                       select new ProjectFileInfo {
                File = File, NamespaceDirectory = Directory
            };
            #endregion



            #region HasReference
            Func <FileInfo, bool> HasReference =
                AssemblyFile =>
            {
                var TargetHintPath = GetRelativePath(
                    ProjectFileName.Directory.FullName,
                    AssemblyFile.FullName
                    );


                return(Enumerable.Any(
                           from ItemGroup in Document.Root.Elements(nsItemGroup)
                           from Reference in ItemGroup.Elements(nsReference)
                           from HintPath in Reference.Elements(nsHintPath)
                           where TargetHintPath == HintPath.Value
                           select new { HintPath, Reference, ItemGroup }
                           ));
            };
            #endregion

            #region GetAssemblyReferences
            Func <FileInfo[]> GetAssemblyReferences =
                delegate
            {
                var a =
                    from ItemGroup in Document.Root.Elements(nsItemGroup)
                    from Reference in ItemGroup.Elements(nsReference)
                    from HintPath in Reference.Elements(nsHintPath)
                    let AssemblyReferencePath = Path.Combine(new FileInfo(filepath).Directory.FullName, HintPath.Value)
                                                select new FileInfo(AssemblyReferencePath);


                //            <Reference Include="My.Solutions.Pages.OpCode.AssetsLibrary">
                //  <HintPath>bin\staging.AssetsLibrary\My.Solutions.Pages.OpCode.AssetsLibrary.dll</HintPath>
                //</Reference>

                return(a.ToArray());
            };
            #endregion

            #region GetProjectReferences
            Func <MSVSProjectFile[]> GetProjectReferences =
                delegate
            {
                var a =
                    from ItemGroup in Document.Root.Elements(nsItemGroup)
                    from ProjectReference in ItemGroup.Elements(nsProjectReference)
                    let Include = ProjectReference.Attribute("Include")
                                  let ProjectReferencePath = Path.Combine(new FileInfo(filepath).Directory.FullName, Include.Value)
                                                             where File.Exists(ProjectReferencePath)
                                                             select(MSVSProjectFile) new FileInfo(ProjectReferencePath);

                //<ItemGroup>
                //  <ProjectReference Include="..\..\My.Solutions.Pages.OpCode\My.Solutions.Pages.OpCode\My.Solutions.Pages.OpCode.csproj">
                //    <Project>{5823d538-ea39-4d2a-9c15-f3bce76c9781}</Project>
                //    <Name>My.Solutions.Pages.OpCode</Name>
                //  </ProjectReference>



                return(a.ToArray());
            };
            #endregion


            MSVSProjectFile __this = null;

            #region AddReference
            Action <FileInfo, AssemblyName> AddReference =
                (AssemblyFile, Name) =>
            {
                /* add reference
                 * <Reference Include="AutoGeneratedReferences.Components.JohDoe.TextComponent, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
                 * <SpecificVersion>False</SpecificVersion>
                 * <HintPath>bin\staging\AutoGeneratedReferences.Components.JohDoe.TextComponent.dll</HintPath>
                 * </Reference>
                 */

                if (!AssemblyFile.Exists)
                {
                    return;
                }

                //var TargetHintPath = AssemblyFile.FullName.Substring(ProjectFileName.Directory.FullName.Length + 1);
                var TargetHintPath = GetRelativePath(
                    ProjectFileName.Directory.FullName,
                    AssemblyFile.FullName
                    );

                // sanity check
                if (!HasReference(AssemblyFile))
                {
                    var TargetItemGroup = Enumerable.First(
                        from ItemGroup in Document.Root.Elements(nsItemGroup)
                        from Reference in ItemGroup.Elements(nsReference)
                        select ItemGroup
                        );

                    TargetItemGroup.Add(
                        new XElement(nsReference,
                                     new XAttribute("Include", Name.ToString()),
                                     new XElement(nsHintPath, TargetHintPath)
                                     )
                        );

                    __this.RaiseReferenceAdded();
                }
            };
            #endregion

            Action Save = delegate
            {
                Document.Save(filepath);
            };

            return(__this = new MSVSProjectFile
            {
                Document = Document,

                HintPaths = HintPaths,
                DefaultNamespace = DefaultNamespace,
                NoneFiles = GetFilesByType(nsNone).ToArray(),
                ContentFiles = GetFilesByType(nsContent).ToArray(),
                HasReference = HasReference,
                AddReference = AddReference,
                Save = Save,
                GetProjectReferences = GetProjectReferences,
                GetAssemblyReferences = GetAssemblyReferences
            });
        }