|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
MotivationWhen a project is finished, many of its code files can be reused in other projects. At first I copy the reusable code files from the first project to the second project. While doing the second project, the reusable code files may be modified for added functionality or improved quality. As the number of projects increases, the reusable code files scatter everywhere. I don't know which copy is the newest. Then I gather the reusable code files together, keep the newest version of each file, make a CodeLib library project and let all other projects reference CodeLib. The CodeLib includes containers, algorithms, mathematics, database SQL wrapper, XML utilities, etc. But if a project uses only a little of CodeLib, the whole library is also shipped with it. This is not very good. Even worse, if project A references both CodeLib and project B. The project B has some code files copied from CodeLib. When using such a type in project A, it is defined twice and the project won't pass compile. Finally I move all the projects into the same folder, make each project include all the files it needs directly. There are no references between projects, the above problem is solved.
However there are new problems:
So I created Project Tool, it does this thing. Thus I achieved better code file organization for code reuse. There are also other advantages:
How Is This Accomplished?1. Load A Solution FileOpen a Visual Studio solution file, use Regular Expression to find out the projects it contains. public class Solution
{
public string FileName;
public List<string> ProjectsFiles = new List<string>();
public List<Project> Projects = new List<Project>();
public IEnumerable<string> GetFileList()
{
MultiSet<string> files = new MultiSet<string>();
foreach (Project project in Projects)
{
files.AddRange(project.GetFilePathList());
}
files.Add(FileName);
return files.Items;
}
public static Solution Load(string solutionFile)
{
Solution solution = new Solution();
Regex regex = new Regex(@"\""(?<file>[^""]*\.csproj)\""",
RegexOptions.Singleline);
foreach (string line in File.ReadAllLines(solutionFile))
{
if (line.StartsWith("Project"))
{
Match match = regex.Match(line);
if (match.Success)
{
solution.ProjectsFiles.Add(match.Groups["file"].Value);
}
}
}
solution.FileName = Path.GetFileName(solutionFile);
string path = Path.GetDirectoryName(solutionFile);
foreach (string projfile in solution.ProjectsFiles)
{
solution.Projects.Add(Project.Load(path, projfile));
}
return solution;
}
}
2. Load ProjectsThe project file is in XML format, so define corresponding fields and use [XmlRoot(Namespace = "http://schemas.microsoft.com/developer/msbuild/2003")]
public class Project
{
[XmlAttribute]
public string DefaultTargets;
[XmlElement("PropertyGroup")]
public List<PropertyGroup> PropertyGroups;
[XmlElement("ItemGroup")]
public List<ItemGroup> ItemGroups;
[XmlIgnore]
public string RelativePath;
[XmlIgnore]
public string FileName;
/// <summary>
/// Load Single Project
/// </summary>
/// <param name="projectfile">full file path</param>
/// <returns></returns>
public static Project Load(string projectfile)
{
Project project = XmlData<Project>.Load(projectfile);
if (project != null)
{
project.FileName = Path.GetFileName(projectfile);
}
return project;
}
/// <summary>
/// Load Solution Project
/// </summary>
/// <param name="path">Solution Path</param>
/// <param name="projectfile">Relative Project Path</param>
/// <returns></returns>
public static Project Load(string path, string projectfile)
{
Project project = XmlData<Project>.Load(Path.Combine(path, projectfile));
if (project != null)
{
project.RelativePath = Path.GetDirectoryName(projectfile);
project.FileName = Path.GetFileName(projectfile);
}
return project;
}
public IEnumerable<string> GetFileList()
{
MultiSet<string> files = new MultiSet<string>();
foreach (ItemGroup group in ItemGroups)
{
foreach (Item item in group.Items)
{
files.Add(item.Include);
}
foreach (Item assembly in group.ReferenceItems)
{
files.Add(Reference.GetFileName(assembly));
}
}
files.Add("bin\\Release\\" + GetOutputFileName());
files.Add(FileName);
return files.Items;
}
public IEnumerable<string> GetFilePathList()
{
if (String.IsNullOrEmpty(RelativePath))
{
foreach (string file in GetFileList())
{
yield return file;
}
}
else
{
foreach (string file in GetFileList())
{
yield return String.Concat(RelativePath, "\\", file);
}
}
}
public string GetOutputFileName()
{
foreach (PropertyGroup group in PropertyGroups)
{
if (group.Condition == null)
{
string extension = GetFillExtension(group.OutputType);
string outputfile = group.AssemblyName + extension;
return outputfile;
}
}
return null;
}
private static string GetFillExtension(string OutputType)
{
switch (OutputType)
{
case "Exe":
case "WinExe":
return ".exe";
case "Library":
return ".dll";
default:
return null;
}
}
}
3. Get All the Files Included in the Projects by Solution.GetFileList()Then you can make a zip archive or count code lines. History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||