Skip to content

Instantly share code, notes, and snippets.

@xeb
Created April 30, 2009 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xeb/104671 to your computer and use it in GitHub Desktop.
Save xeb/104671 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Collections;
namespace Add2Project
{
/// <summary>
/// This App will automatically add missing files to a .csproj file that existing with a given root directory.
/// </summary>
class Program
{
private static int _files = 0;
private static string _root = string.Empty;
private static XmlNamespaceManager _xnm = null;
private static string _xnamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
private static ArrayList _ignoreExtensions = new ArrayList(new string[] { ".csproj", ".config", ".backup", ".user" });
private static ArrayList _ignoreDirectories = new ArrayList(new string[] { "bin", "App_Data", "App_Code", "obj", "Properties", ".svn" });
static void Main(string[] args)
{
if (args.Length == 0)
{
DisplayUsage(string.Empty);
return;
}
string projectFile = args[0];
string directoryPath = args.Length == 2 ? args[1] : ".";
if (!File.Exists(projectFile))
{
DisplayUsage(string.Format("Could not find Project: '{0}'", projectFile));
return;
}
if (!Directory.Exists(directoryPath))
{
DisplayUsage(string.Format("Could not find Directory: '{0}'", directoryPath));
return;
}
Backup(projectFile);
_root = directoryPath;
DirectoryInfo di = new DirectoryInfo(directoryPath);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(projectFile);
_xnm = new XmlNamespaceManager(xdoc.NameTable);
_xnm.AddNamespace("p", _xnamespace);
AddFiles(di, ref xdoc);
xdoc.Save(projectFile);
Console.WriteLine(string.Format("{0} files have been added", _files));
}
static void AddFiles(DirectoryInfo di, ref XmlDocument xdoc)
{
foreach (FileInfo fi in di.GetFiles())
{
if (!_ignoreExtensions.Contains(fi.Extension))
{
string include = fi.FullName.Replace(_root, "");
string nodeType = GetNodeType(fi.Extension);
string xpath = string.Format("p:ItemGroup/p:{0}[@Include = '{1}']", nodeType, include);
XmlNode node = xdoc.DocumentElement.SelectSingleNode(xpath, _xnm);
if (node == null)
{
// Find the Parent of similar nodes
XmlNode sample = xdoc.DocumentElement.SelectSingleNode(string.Format("p:ItemGroup/p:{0}", nodeType), _xnm);
XmlNode newNode = xdoc.CreateNode(sample.NodeType, nodeType, _xnamespace);
XmlAttribute attr = xdoc.CreateAttribute("Include");
attr.Value = include;
newNode.Attributes.Append(attr);
sample.ParentNode.InsertAfter(newNode, sample);
_files++;
}
}
}
foreach (DirectoryInfo cdi in di.GetDirectories())
{
if (!_ignoreDirectories.Contains(cdi.Name))
{
AddFiles(cdi, ref xdoc);
}
}
}
static string GetNodeType(string extension)
{
string nodeName = string.Empty;
switch (extension)
{
case ".cs":
nodeName = "Compile";
break;
case ".aspx":
case ".js":
case ".sass":
case ".asax":
case ".css":
case ".config":
case ".gif":
case ".jpg":
case ".jpeg":
nodeName = "Content";
break;
case ".haml":
case ".rb":
nodeName = "None";
break;
default:
throw new Exception("Could not determine type for extension: " + extension);
break;
}
return nodeName;
}
static void Backup(string fileName)
{
if (File.Exists(fileName + ".backup"))
{
File.Delete(fileName + ".backup");
}
File.Copy(fileName, fileName + ".backup");
}
static void DisplayUsage(string msg)
{
if (!string.IsNullOrEmpty(msg))
{
Console.WriteLine(msg);
}
Console.WriteLine("Usage: add2project.exe ProjectFile.csproj (OptionalFilePath)");
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment