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