html2chm

C# version of turning a website into a chm file. Requires that html workshop (http://msdn.microsoft.com/library/en-us/htmlhelp/html/vsconhh1start.asp) is installed. If anyone knows of a working open source chm compiler let me know.

Can be used like: html2chm.Html2chm action = new html2chm.Html2chm(); This will run and prompt you for which website directory and which file in the directory to convert to a chm file.

Or it can be used like this: bool eachFileAsTopic = true; html2chm.Html2chm action = new html2chm.Html2chm(@”\Path\to\directory\to\convert”, @”mainTopic.html”, eachFileAsTopic);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;


namespace html2chm
{

    public class Html2chm
    {
        //http://www.majorsilence.com/csharp_html2chm
        //The generated CHM file is named YourCHMFile.chm on your desktop.

        string HHC;
        // Path to hhc.exe

        // Directory path where HHP file is stored
        // and base directory of the html files to be converted
        string RepBase;

        string FicHHP;
        // Path to HHP file

        string fileListString;


        public Html2chm() : this("", "", false)
        {
        }

        public Html2chm(string convertDirectory, string mainTopic, bool filesAsTopics)
        {
            List<string> fileList = new List<string>();

            HHC = System.IO.Path.Combine("C:\\Program Files\\HTML Help Workshop", "hhc.exe");

            if (System.IO.File.Exists(HHC) == false)
            {
                HHC = System.IO.Path.Combine("C:\\Program Files (x86)\\HTML Help Workshop", "hhc.exe");
                if (System.IO.File.Exists(HHC) == false)
                {
                    MessageBox.Show("In order to use this script, you need HTML Help Workshop" + System.Environment.NewLine + "http://msdn.microsoft.com/library/en-us/htmlhelp/html/vsconhh1start.asp");
                    return;
                }
            }

            if (convertDirectory == string.Empty)
            {
                System.Windows.Forms.FolderBrowserDialog DirectoryBrowser = default(System.Windows.Forms.FolderBrowserDialog);
                DirectoryBrowser = new System.Windows.Forms.FolderBrowserDialog();
                DirectoryBrowser.Description = "Which directory do you want to use?";
                if ((DirectoryBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK))
                {
                    RepBase = DirectoryBrowser.SelectedPath;
                }
            }
            else
            {
                RepBase = convertDirectory;
            }


            if (RepBase == null)
            {

                MessageBox.Show("Please choose a Folder");
            }
            else
            {
                fileList.AddRange(RecursiveFileList(new DirectoryInfo(RepBase), new DirectoryInfo(RepBase)));
                string fileHHC="";
                string FicHHC = System.IO.Path.Combine(RepBase, "chm-editor-Temp-HHC.hhc");
                foreach (string s in fileList)
                {
                    this.fileListString += s + System.Environment.NewLine;

                    if (filesAsTopics)
                    {
                        string value = s.Replace(RepBase, "");

                        string textValue = ""; 

                        if (value.StartsWith("\\"))
                        {
                            value = value.Remove(0, 1);
                        }

                        textValue = System.IO.Path.GetFileName(value); 
                        textValue = textValue.Replace(System.IO.Path.GetExtension(textValue), "");

                        fileHHC += "<LI><OBJECT type=\"text/sitemap\"><PARAM name=\"Name\" value=\"" + textValue + "\"><PARAM name=\"Local\" value=\"" + value + "\"><PARAM name=\"ImageNumber\" value=\"0\"></OBJECT>";
                    }
                }

                if (filesAsTopics)
                {
                    System.IO.File.WriteAllText(FicHHC, fileHHC);
                }

                FicHHP = System.IO.Path.Combine(RepBase, "chm-editor-Temp" + DateTime.Now.Millisecond.ToString() + ".HHP");
                string output = "[OPTIONS]" + System.Environment.NewLine;
                output += "Compatibility=1.1 or later" + System.Environment.NewLine;
                output += "Compiled file=" + System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "YourCHMFile.chm") + System.Environment.NewLine;
                string main_topic;

                if (mainTopic == string.Empty)
                {
                    main_topic = MainTopic();
                }
                else
                {
                    main_topic = mainTopic;
                }

                if (filesAsTopics)
                {
                    output += "Contents file=" + FicHHC + System.Environment.NewLine;
                }

                output += "Default topic=" + main_topic.Substring(RepBase.Length + 1, main_topic.Length - (RepBase.Length + 1)) + System.Environment.NewLine; //Strings.Mid(MainTopic(), Strings.Len(RepBase) + 2) + System.Environment.NewLine;
                output += "Display compile progress=No" + System.Environment.NewLine;
                output += "Language=0x409 English (standard)" + System.Environment.NewLine;
                // 0x40C - French
                // 0x407 - German
                output += "Title=(c) 2010 MajorSilence" + System.Environment.NewLine;
                output += System.Environment.NewLine + "[FILES]" + System.Environment.NewLine;
                output += this.fileListString + System.Environment.NewLine;
                output += System.Environment.NewLine + "[INFOTYPES]" + System.Environment.NewLine;

                System.IO.File.WriteAllText(FicHHP, output);

                System.Diagnostics.Process p = new System.Diagnostics.Process();
                p.StartInfo.FileName = HHC;
                p.StartInfo.Arguments = FicHHP;
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                p.WaitForExit();

                // Finally Remove 
                try
                {
                    System.IO.File.Delete(FicHHP);

                    if (System.IO.File.Exists(FicHHC))
                    {
                        System.IO.File.Delete(FicHHC);
                    }
                }
                catch (Exception ex)
                {
                }
            }

            
        }

        // Recurse through directory and return string of files
        public List<String> RecursiveFileList(DirectoryInfo source, DirectoryInfo target)
        {
            // loop through each file in current directory
            List<string> fileList = new List<string>();

            foreach (FileInfo file in source.GetFiles())
            {
                if (file.Name.ToLower().EndsWith("html") | file.Name.ToLower().EndsWith("htm") | file.Name.ToLower().EndsWith("mov") | file.Name.ToLower().EndsWith("au"))
                {
                    fileList.Add(file.FullName);

                }
            }

            // Then loop through each directory
            foreach (DirectoryInfo dir in source.GetDirectories())
            {
                fileList.AddRange(RecursiveFileList(dir, new DirectoryInfo(dir.Name)));
            }


            return fileList;
        }


        // Select the root file (Main topic) in base directory
        public string MainTopic()
        {
            System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog();

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                return dlg.FileName;
            }

            return string.Empty;
        }

    }

}