using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Web.RegularExpressions;
using System.Text.RegularExpressions;
using System.Diagnostics; //added additional DLL to references
namespace RemoveCodeBehindFromAscx
{
class Program
{
static int Main(string[] args)
{
int nRet = -1;
if (args.Length >= 2) return nRet = ProcessDirectory(args[0],args[1]);
else
{
Console.WriteLine("Utility should be called:");
Console.WriteLine(AssemblyTitle(Assembly.GetExecutingAssembly()) + " source destination");
Console.WriteLine("Press enter to close the application");
Console.ReadLine();
}
return nRet;
}
public static int ProcessDirectory(string srcFiles, string targetDirectory)
{
// Process the list of files found in the directory.
Debug.WriteLine("ProcessDirectory:" + srcFiles);
string pathDir = Path.GetDirectoryName(srcFiles); //without trailin '/'
string searchPattern = Path.GetFileName(srcFiles);// srcFiles.Remove(0, pathDir.Length + 1); //
return ProcessDirectory(pathDir, searchPattern, targetDirectory);
}
public static int ProcessDirectory(string pathDir, string searchPattern, string targetDirectory)
{
// Process the list of files found in the directory.
//Debug.WriteLine("ProcessDirectory:" + srcFiles);
//string pathDir = Path.GetDirectoryName(srcFiles); //without trailin '/'
//string searchPattern = Path.GetFileName(srcFiles);// srcFiles.Remove(0, pathDir.Length + 1); //
string[] fileEntries = Directory.GetFiles(pathDir, searchPattern);
foreach (string fileName in fileEntries)
{
string sExt = GetFileExtensionWithoutDot(fileName).ToLower();// 'remove forward '.'
switch (sExt)
{
case "ascx":
ProcessFile(fileName, targetDirectory);
break;
default://do nothing
break;
}
}
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(pathDir);
foreach (string subdirectory in subdirectoryEntries)
{
string targetPath = Path.Combine(targetDirectory, Path.GetFileName(subdirectory));
ProcessDirectory(subdirectory, searchPattern, targetPath);
}
return 0;
}
// Insert logic for processing found files here.
public static void ProcessFile(string path, string targetDirectory)
{
string FileName= Path.GetFileName(path) ;
StreamReader strmIn = new StreamReader(path);
if (!Directory.Exists(targetDirectory))
Directory.CreateDirectory(targetDirectory);
string sPath=Path.Combine(targetDirectory, FileName);
MakeWritable(sPath); //in case it is read-only
StreamWriter strmOut = new StreamWriter(sPath);
DirectiveRegex rxDirective = new DirectiveRegex();
PrintRegexGroups(rxDirective, "DirectiveRegex");
string str;
while( (str = strmIn.ReadLine())!=null)
{
string sCodeBehindAttr="";
Match m=rxDirective.Match(str);
if (m.Success)
{//Directive found
PrintMatch(m, "directive");
string sDirectiveName = m.Groups[1].Captures[0].Value ; //in Group1, capture0 should be directive name
sDirectiveName=sDirectiveName.Trim().ToLower();
if (sDirectiveName.ToLower() == "control")
{
//todo may be flag that control directive is found, and do not need to check more - should be one control directive per file
//find in m.Groups[1].Captures entry started with " Codebehind=" and remenber it
CaptureCollection cc = m.Groups[1].Captures;
for (int j = 0; j < cc.Count; j++)
{
string sCapture= cc[j].Value ;
if (sCapture.Trim().ToLower().StartsWith("codebehind="))
{ sCodeBehindAttr=sCapture;
break;
}
}
}
}
if(sCodeBehindAttr.Length>0)
{
str=str.Replace(sCodeBehindAttr,"");
}
strmOut.WriteLine(str);
}
strmIn.Close();
strmOut.Close();
}
#region "helper methods"
public static string GetFileExtensionWithoutDot(string fileName)
{
string sExt = Path.GetExtension(fileName);
if ((null == sExt) | (sExt == string.Empty))
return string.Empty;
return sExt.Remove(0, 1);
}
public static string AssemblyTitle(Assembly asm)
{ // 'From http://www.dotnet247.com/247reference/msgs/15/78041.aspx
AssemblyTitleAttribute attribute1 = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(asm, typeof(AssemblyTitleAttribute));
// 'Application.ProductName is not working in Dll
// 'Assembly.GetEntryAssembly().FullName not reliable ?? see http://weblogs.asp.net/asanto/posts/26710.aspx
string sRet = attribute1.Title;
if (String.IsNullOrEmpty(sRet))
{
sRet = asm.GetName().Name;
}
return sRet;
}
[Conditional("DEBUG")]
public static void PrintMatch(Match m, string sComment)
{
PrintIfNotEmpty(sComment);
Debug.Write(" Success =" + m.Success);
Debug.WriteLine(" Groups.Count=" + m.Groups.Count);
for (int i = 0; i < m.Groups.Count ; i++)
{
Group g = m.Groups[i];
Debug.WriteLine("Group" + i + "='" + g + "'");
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
Debug.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index);
}
}
}
[Conditional("DEBUG")]
public static void PrintMatchCollection(MatchCollection matches, string sComment)
{
PrintIfNotEmpty(sComment);
//string sRet = "";
//foreach (Match m in matches)
for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
PrintMatch(m, "Match " + i);
}
}
[Conditional("DEBUG")]
public static void PrintRegexGroups(Regex rx, string sComment)
{
PrintIfNotEmpty(sComment);
int[] numbers = rx.GetGroupNumbers();
foreach (int n in numbers)
{
Debug.WriteLine("Group " + n + " name: " + rx.GroupNameFromNumber(n));
}
}
private static void PrintIfNotEmpty(string sComment)
{
if (!String.IsNullOrEmpty(sComment))
{
Debug.WriteLine(sComment);
}
}
//sourced from internal HtmlAgilityPack IOLibrary http://smourier.blogspot.com/2005/05/net-html-agility-pack-how-to-use.html
public static void MakeWritable(string path)
{
if (!File.Exists(path))
return;
File.SetAttributes(path, File.GetAttributes(path) & ~FileAttributes.ReadOnly);
}
#endregion //"helper methods"
}
}