Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#
Article

Project Tool

Rate me:
Please Sign up or sign in to vote.
4.69/5 (10 votes)
23 Sep 2007CPOL3 min read 54.5K   1.6K   73   7
Backup your C# solution and projects for archive or source code sharing. Temporary or unused files are excluded.
Sample Image - ProjectTool.gif

Motivation

When 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.

Projects.png

However there are new problems:

  • Visual Studio doesn't allow creation of multiple projects in the same folder.

    This is easy, make a copy of a template project file (NewProject.csproj), rename the copied file, open it using Visual Studio, click show all files and include the files you need.

  • Multiple projects can't share the same Properties folder if they have different application settings.

    I created a AppSettings class and a CodeGenerator, the Settings.cs is generated from Settings.txt. The following code does the rest:

    C#
    public Form1()
    {
        InitializeComponent();
        LoadSettings();
    }
    private void LoadSettings()
    {
        Settings.Default.Set(fbProject, "FolderPath", "ProjectPath");
        Settings.Default.Set(fbBackup, "FolderPath", "BackupPath");
        Settings.Default.Set(fbFramework, "FolderPath", "FrameworkPath");
        FormClosing += delegate { Settings.Default.Save(); };
    }
  • It is difficult to pick out all the files belonging to a project, when you backup the project or share your source code with others.

So I created Project Tool, it does this thing.

Thus I achieved better code file organization for code reuse.

There are also other advantages:

  • All code files a project needs are compiled into one file. It is easy to distribute and gains performance at least in theory.
  • All the projects share the same bin\release folder and obj folder. This reduces the number of directories created. When you launch applications, it is easy to find them in one place. Furthermore third party libraries such as ICSharpCode.SharpZipLib.dll, MySql.Data.dll exist as one copy in your hard disk.
  • Make a copy of the csproj file, by including different one or excluding program.cs, you can make different versions (windows, console, library) of the same project.

How Is This Accomplished?

1. Load A Solution File

Open a Visual Studio solution file, use Regular Expression to find out the projects it contains.

C#
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(@&quot;\&quot;&quot;(?<file>[^&quot;&quot;]*\.csproj)\&quot;&quot;&quot;,
             RegexOptions.Singleline);
         foreach (string line in File.ReadAllLines(solutionFile))
         {
             if (line.StartsWith(&quot;Project&quot;))
             {
                 Match match = regex.Match(line);
                 if (match.Success)
                 {
                     solution.ProjectsFiles.Add(match.Groups[&quot;file&quot;].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 Projects

The project file is in XML format, so define corresponding fields and use XmlSerializer to deserialize it.

C#
[XmlRoot(Namespace = &quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;)]
public class Project
{
    [XmlAttribute]
    public string DefaultTargets;
    [XmlElement(&quot;PropertyGroup&quot;)]
    public List<PropertyGroup> PropertyGroups;
    [XmlElement(&quot;ItemGroup&quot;)]
    public List<ItemGroup> ItemGroups;
    [XmlIgnore]
    public string RelativePath;
    [XmlIgnore]
    public string FileName;
    /// <summary>
    /// Load Single Project
    /// </summary>
    /// <param name=&quot;projectfile&quot;>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=&quot;path&quot;>Solution Path</param>
    /// <param name=&quot;projectfile&quot;>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(&quot;bin\\Release\\&quot; + 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, &quot;\\&quot;, 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 &quot;Exe&quot;:
            case &quot;WinExe&quot;:
                return &quot;.exe&quot;;
            case &quot;Library&quot;:
                return &quot;.dll&quot;;
            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

  • 2006-05-16
    • Backup project files
    • Count code lines
  • 2006-06-01
    • Build project
  • 2006-08-31
    • Include referenced assemblies and compiled file when you backup
    • Open and backup solution with multiple projects
  • 2006-09-01
    • Show file icon in treeview
    • Set Language in settings: Chinese or English
  • 2006-09-11
    • Include referenced project's output DLL file
  • 2006-10-16
    • Replaced ICSharpCode.SharpZipLib with my own implementation of deflate algorithm and zip format
    • Then the last write time of files are maintained. Compresses better but slower.
  • 2006-12-03
    • Use file name template to automatically generate archive file name
    • Create differential backup file compared to a given date
  • 2007-09-21
    • The "List" button is removed and its functionality is activated when project path changed
    • Display "please wait" message while backing up
    • Remember last solution and reopen it next time
    • Empty backup file name like ".zip" is avoided
    • Add functionality of synchronize two folders according to last modified time of files
    • Include files in website project

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect YunCheDa Hangzhou
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey7-Feb-12 18:56
professionalManoj Kumar Choubey7-Feb-12 18:56 
GeneralHi Pin
bommc200321-Jul-08 22:04
bommc200321-Jul-08 22:04 
GeneralImprovements suggestions Pin
Orenk925-Feb-07 18:16
Orenk925-Feb-07 18:16 
GeneralRe: Improvements suggestions Pin
Liu Junfeng23-Sep-07 17:31
Liu Junfeng23-Sep-07 17:31 
QuestionDifference from a source control tool? Pin
Warren Stevens4-Dec-06 5:05
Warren Stevens4-Dec-06 5:05 
GeneralAbout the Backup feature Pin
Alexandru Matei23-Nov-06 1:20
Alexandru Matei23-Nov-06 1:20 
AnswerRe: About the Backup feature Pin
Liu Junfeng4-Dec-06 0:50
Liu Junfeng4-Dec-06 0:50 
OK, added these two features.
To backup only some files, click checkboxes on the File tabpage.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.