Click here to Skip to main content
Click here to Skip to main content

Project Tool

, 23 Sep 2007
Rate this:
Please Sign up or sign in to vote.
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:

    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.

   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.

    [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;
        /// <span class="code-SummaryComment"><summary></span>
        /// Load Single Project
        /// <span class="code-SummaryComment"></summary></span>
        /// <span class="code-SummaryComment"><param name=&quot;projectfile&quot;>full file path</param></span>
        /// <span class="code-SummaryComment"><returns></returns></span>
        public static Project Load(string projectfile)
        {
            Project project = XmlData<Project>.Load(projectfile);
            if (project != null)
            {
                project.FileName = Path.GetFileName(projectfile);
            }
            return project;
        }
        /// <span class="code-SummaryComment"><summary></span>
        /// Load Solution Project
        /// <span class="code-SummaryComment"></summary></span>
        /// <span class="code-SummaryComment"><param name=&quot;path&quot;>Solution Path</param></span>
        /// <span class="code-SummaryComment"><param name=&quot;projectfile&quot;>Relative Project Path</param></span>
        /// <span class="code-SummaryComment"><returns></returns></span>
        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)

About the Author

Liu Junfeng
Software Developer (Senior) Beyondsoft SH
China China
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey7-Feb-12 18:56 
GeneralHi Pinmemberbommc200321-Jul-08 22:04 
GeneralImprovements suggestions PinmemberOrenk925-Feb-07 18:16 
GeneralRe: Improvements suggestions PinmemberLiu Junfeng23-Sep-07 17:31 
QuestionDifference from a source control tool? PinmemberWarren Stevens4-Dec-06 5:05 
GeneralAbout the Backup feature PinmemberAlexandru Matei23-Nov-06 1:20 
Hello,
 
Congratulations for your work!
 
I really enjoy the project Backup feature. If you have time, please consider these two suggestions: (I apologize if they are already implemented)
 
Please add these two checkboxes to the Backup tab :
[X] ZIP to distinct archive
[X] ZIP only files that changed since the last FULL backup
 
So what I suggest
1. easily create backup files like these:
WebApplication_20061123_1230.zip
WebApplication_20061123_1240.zip
WebApplication_20061123_1250.zip
 
Where "20061123" represents the current date November 23, 2006
and "1230", "1240", etc represent the current time in 24 hours clock : 12:30
 

2. Backup only some files, not all. Please read this link too.
 
http://www.backup4all.com/differential-backup.php[^]
 
Thank you very much!

AnswerRe: About the Backup feature PinmemberLiu Junfeng4-Dec-06 0:50 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 23 Sep 2007
Article Copyright 2006 by Liu Junfeng
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid