From 168d545a4ff98ef7dddd7c4d9ea2c77e69e00a81 Mon Sep 17 00:00:00 2001 From: Mathias Simmack Date: Thu, 20 Jul 2006 19:18:52 +0000 Subject: [PATCH] uploaded a new version of my Help 2.0 register tool including its source git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1604 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- src/Tools/Help/Help2Register.exe | Bin 32768 -> 45056 bytes src/Tools/Help/MSHelpServices.dll | Bin 45056 -> 45056 bytes src/Tools/Help/plugins.xml | 2 +- src/Tools/Help/register.xml | 2 +- src/Tools/Help/register.xsd | 8 +- .../Help/source/Configuration/AssemblyInfo.cs | 39 ++ .../Help/source/CreateMsHelpAssembly.bat | 18 + src/Tools/Help/source/Help2Register.csproj | 70 ++++ src/Tools/Help/source/Help2Register.sln | 16 + .../HelperClasses/ApplicationHelpers.cs | 90 +++++ .../HelperClasses/MergeNamespaceClass.cs | 38 ++ .../source/HelperClasses/PluginSearchClass.cs | 156 ++++++++ .../source/HelperClasses/RegistrationClass.cs | 332 ++++++++++++++++++ .../source/HelperClasses/ResourcesHelper.cs | 27 ++ .../source/HelperClasses/XmlHelperClass.cs | 121 +++++++ .../source/HelperClasses/XmlValidatorClass.cs | 50 +++ .../source/ItemClasses/DocumentItemClass.cs | 102 ++++++ .../source/ItemClasses/FilterItemClass.cs | 46 +++ .../source/ItemClasses/ICommonItemClass.cs | 12 + .../source/ItemClasses/ItemEventHandling.cs | 89 +++++ .../source/ItemClasses/NamespaceItemClass.cs | 152 ++++++++ .../source/ItemClasses/NamespacesItemClass.cs | 285 +++++++++++++++ .../source/ItemClasses/PluginItemClass.cs | 115 ++++++ .../source/ItemClasses/PluginsItemClass.cs | 186 ++++++++++ src/Tools/Help/source/MSHelpServices.dll | Bin 0 -> 45056 bytes src/Tools/Help/source/String.resources | Bin 0 -> 1928 bytes src/Tools/Help/source/register.cs | 254 ++++++++++++++ 27 files changed, 2206 insertions(+), 4 deletions(-) create mode 100644 src/Tools/Help/source/Configuration/AssemblyInfo.cs create mode 100644 src/Tools/Help/source/CreateMsHelpAssembly.bat create mode 100644 src/Tools/Help/source/Help2Register.csproj create mode 100644 src/Tools/Help/source/Help2Register.sln create mode 100644 src/Tools/Help/source/HelperClasses/ApplicationHelpers.cs create mode 100644 src/Tools/Help/source/HelperClasses/MergeNamespaceClass.cs create mode 100644 src/Tools/Help/source/HelperClasses/PluginSearchClass.cs create mode 100644 src/Tools/Help/source/HelperClasses/RegistrationClass.cs create mode 100644 src/Tools/Help/source/HelperClasses/ResourcesHelper.cs create mode 100644 src/Tools/Help/source/HelperClasses/XmlHelperClass.cs create mode 100644 src/Tools/Help/source/HelperClasses/XmlValidatorClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/DocumentItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/FilterItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/ICommonItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/ItemEventHandling.cs create mode 100644 src/Tools/Help/source/ItemClasses/NamespaceItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/NamespacesItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/PluginItemClass.cs create mode 100644 src/Tools/Help/source/ItemClasses/PluginsItemClass.cs create mode 100644 src/Tools/Help/source/MSHelpServices.dll create mode 100644 src/Tools/Help/source/String.resources create mode 100644 src/Tools/Help/source/register.cs diff --git a/src/Tools/Help/Help2Register.exe b/src/Tools/Help/Help2Register.exe index 756b61bebe82e1447505ed0060816f2e47be7c17..1dd7d033fa92d9436e31bf06dbaa00143182b617 100644 GIT binary patch literal 45056 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 REHGn%84Ju<;Qs{+{BM%doU#A_ literal 32768 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 X0(A@2El{^W-2!zB)GhE^VuAk$Y^;;n diff --git a/src/Tools/Help/MSHelpServices.dll b/src/Tools/Help/MSHelpServices.dll index 97a6d34705d73739e47dd635d533ee733cd74e23..aa890731f410f24fad2beab638fc0b4ded394649 100644 GIT binary patch literal 45056 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 L=)!v!V*@Tf`HVxdDp=#ERieh95RZ*& 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 diff --git a/src/Tools/Help/plugins.xml b/src/Tools/Help/plugins.xml index c92ccae63b..048dd1ee0b 100644 --- a/src/Tools/Help/plugins.xml +++ b/src/Tools/Help/plugins.xml @@ -1,5 +1,5 @@ - + diff --git a/src/Tools/Help/register.xml b/src/Tools/Help/register.xml index c42ee7c22d..26b70eaadf 100644 --- a/src/Tools/Help/register.xml +++ b/src/Tools/Help/register.xml @@ -1,5 +1,5 @@ - + diff --git a/src/Tools/Help/register.xsd b/src/Tools/Help/register.xsd index bc7179d9cf..9f9fb5d2a3 100644 --- a/src/Tools/Help/register.xsd +++ b/src/Tools/Help/register.xsd @@ -1,6 +1,10 @@ - - + Help 2.0 Registration Validation Schema Copyright (c) 2005 Mathias Simmack diff --git a/src/Tools/Help/source/Configuration/AssemblyInfo.cs b/src/Tools/Help/source/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..b7550ef4d1 --- /dev/null +++ b/src/Tools/Help/source/Configuration/AssemblyInfo.cs @@ -0,0 +1,39 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("Help 2.0 Registration Utility")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Cube")] +[assembly: AssemblyProduct("Help 2.0 Utilities")] +[assembly: AssemblyCopyright("Copyright (c) 2005 Mathias Simmack")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("3.0.*")] + +// The following attributes specify the key for the sign of your assembly. See the +// .NET Framework documentation for more information about signing. +// This is not required, if you don't want signing let these attributes like they're. +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] + +[assembly: CLSCompliant(false)] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)] +[assembly: ComVisibleAttribute(false)] diff --git a/src/Tools/Help/source/CreateMsHelpAssembly.bat b/src/Tools/Help/source/CreateMsHelpAssembly.bat new file mode 100644 index 0000000000..3af8dbd151 --- /dev/null +++ b/src/Tools/Help/source/CreateMsHelpAssembly.bat @@ -0,0 +1,18 @@ +@echo off +setlocal +set AxImp="%ProgramFiles%\Microsoft.NET\SDK\v2.0\Bin\AxImp.exe" +set Help2Library="%CommonProgramFiles%\Microsoft Shared\help\hxvz.dll" + + +if exist Ax*.dll del Ax*.dll +if exist MSHelp*.dll del MSHelp*.dll + +%AxImp% %Help2Library% + +del Ax*.dll +del MSHelpControls.dll + +set Help2Library= +set AxImp= + +pause \ No newline at end of file diff --git a/src/Tools/Help/source/Help2Register.csproj b/src/Tools/Help/source/Help2Register.csproj new file mode 100644 index 0000000000..3f56e270e5 --- /dev/null +++ b/src/Tools/Help/source/Help2Register.csproj @@ -0,0 +1,70 @@ + + + Exe + Help2Register + Help2Register + Release + AnyCPU + {10C38AE6-0491-4677-BA39-5A2A8C704544} + False + True + False + None + False + Auto + 4194304 + AnyCPU + 4096 + 4 + false + false + False + + False + File + + + .. + true + DEBUG;TRACE + + + .. + true + TRACE + + + + + + MSHelpServices.dll + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tools/Help/source/Help2Register.sln b/src/Tools/Help/source/Help2Register.sln new file mode 100644 index 0000000000..650d959826 --- /dev/null +++ b/src/Tools/Help/source/Help2Register.sln @@ -0,0 +1,16 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# SharpDevelop 2.1.0.1596 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Help2Register", "Help2Register.csproj", "{10C38AE6-0491-4677-BA39-5A2A8C704544}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {10C38AE6-0491-4677-BA39-5A2A8C704544}.Debug|Any CPU.Build.0 = Debug|Any CPU + {10C38AE6-0491-4677-BA39-5A2A8C704544}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {10C38AE6-0491-4677-BA39-5A2A8C704544}.Release|Any CPU.Build.0 = Release|Any CPU + {10C38AE6-0491-4677-BA39-5A2A8C704544}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/Tools/Help/source/HelperClasses/ApplicationHelpers.cs b/src/Tools/Help/source/HelperClasses/ApplicationHelpers.cs new file mode 100644 index 0000000000..bfa251fee2 --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/ApplicationHelpers.cs @@ -0,0 +1,90 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Security; + using System.Security.Permissions; + using System.Security.Principal; + using System.Threading; + using Microsoft.Win32; + + public sealed class ApplicationHelpers + { + public const string Help2NamespaceUri = "http://www.simmack.de/2006/help2"; + + ApplicationHelpers() + { + } + + public static bool IsClassRegistered(string classId) + { + try + { + RegistryKey tmp = Registry.ClassesRoot.OpenSubKey + (string.Format(CultureInfo.InvariantCulture, @"CLSID\{0}\InprocServer32", classId), false); + string help2Library = (string)tmp.GetValue("", string.Empty); + tmp.Close(); + + return (!string.IsNullOrEmpty(help2Library) && File.Exists(help2Library)); + } + catch (ArgumentException) + { + } + catch (SecurityException) + { + } + return false; + } + + [PermissionSet(SecurityAction.LinkDemand, Name="Execution")] + public static void KillIllegalProcesses(string[] invalidProcesses) + { + if (invalidProcesses == null || invalidProcesses.Length == 0) + { + return; + } + + Process[] runningProcesses = Process.GetProcesses(); + foreach (Process currentProcess in runningProcesses) + { + try + { + string fileName = Path.GetFileName(currentProcess.MainModule.FileName); + foreach (string invalidProcess in invalidProcesses) + { + if (string.Compare(invalidProcess.ToLower(CultureInfo.InvariantCulture), + fileName.ToLower(CultureInfo.InvariantCulture)) == 0) + { + currentProcess.Kill(); + currentProcess.WaitForExit(); + } + } + } + catch (System.ComponentModel.Win32Exception) + { + } + } + } + + public static bool IsThisUserPrivileged() + { + switch(Environment.OSVersion.Platform) + { + case PlatformID.Win32NT: + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); + WindowsPrincipal wp = (Thread.CurrentPrincipal as WindowsPrincipal); + return (wp.IsInRole(WindowsBuiltInRole.Administrator) || wp.IsInRole(WindowsBuiltInRole.PowerUser)); + case PlatformID.Win32Windows: + return true; + default: + return false; + } + } + } +} diff --git a/src/Tools/Help/source/HelperClasses/MergeNamespaceClass.cs b/src/Tools/Help/source/HelperClasses/MergeNamespaceClass.cs new file mode 100644 index 0000000000..3fbeb861c9 --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/MergeNamespaceClass.cs @@ -0,0 +1,38 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Globalization; + using HtmlHelp2Registration.ItemClasses; + using MSHelpServices; + + public sealed class MergeNamespace + { + MergeNamespace() + { + } + + public static void CallMerge(string namespaceName) + { + try + { + HxSessionClass session = new HxSessionClass(); + session.Initialize(string.Format(CultureInfo.InvariantCulture, "ms-help://{0}", namespaceName), 0); + + // Next lesson about the Help 2.0 API: You have to wait until + // "MergeIndex" is ready. This is a console tool, so ... But + // if you want to do it with a GUI tool, you have to use a + // thread or something. I used a thread in my Delphi version. + + IHxCollection collection = session.Collection; + collection.MergeIndex(); + } + catch (System.Runtime.InteropServices.COMException) + { + } + } + } +} diff --git a/src/Tools/Help/source/HelperClasses/PluginSearchClass.cs b/src/Tools/Help/source/HelperClasses/PluginSearchClass.cs new file mode 100644 index 0000000000..1408847080 --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/PluginSearchClass.cs @@ -0,0 +1,156 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Collections.Specialized; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Runtime.InteropServices; + using MSHelpServices; + + public sealed class PluginSearch + { + PluginSearch() + { + } + + public static bool PluginDoesExist(string namespaceName, string pluginName) + { + if (string.IsNullOrEmpty(namespaceName) || string.IsNullOrEmpty(pluginName)) + { + return false; + } + + try + { + HxRegistryWalkerClass registryWalker = new HxRegistryWalkerClass(); + IHxRegNamespaceList help2Namespaces = registryWalker.get_RegisteredNamespaceList(""); + + foreach (IHxRegNamespace currentNamespace in help2Namespaces) + { + if (string.Compare(currentNamespace.Name, namespaceName) == 0) + { + IHxRegPlugInList p = + (IHxRegPlugInList)currentNamespace.GetProperty(HxRegNamespacePropId.HxRegNamespacePlugInList); + foreach (IHxRegPlugIn plugin in p) + { + string currentName = (string)plugin.GetProperty(HxRegPlugInPropId.HxRegPlugInName); + if (string.Compare(currentName, pluginName) == 0) + { + return true; + } + } + } + } + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public static StringCollection FindPlugin(string pluginName) + { + StringCollection namespaces = new StringCollection(); + try + { + HxRegistryWalkerClass registryWalker = new HxRegistryWalkerClass(); + IHxRegNamespaceList help2Namespaces = registryWalker.get_RegisteredNamespaceList(""); + + foreach (IHxRegNamespace currentNamespace in help2Namespaces) + { + IHxRegPlugInList p = + (IHxRegPlugInList)currentNamespace.GetProperty(HxRegNamespacePropId.HxRegNamespacePlugInList); + foreach (IHxRegPlugIn plugin in p) + { + string currentName = (string)plugin.GetProperty(HxRegPlugInPropId.HxRegPlugInName); + if (string.Compare(currentName, pluginName) == 0) + { + namespaces.Add(currentNamespace.Name); + break; + } + } + } + } + catch (System.Runtime.InteropServices.COMException) + { + } + return namespaces; + } + + public static ReadOnlyCollection FindPluginAsGenericList(string pluginName) + { + List namespaces = new List(); + try + { + HxRegistryWalkerClass registryWalker = new HxRegistryWalkerClass(); + IHxRegNamespaceList help2Namespaces = registryWalker.get_RegisteredNamespaceList(""); + + foreach (IHxRegNamespace currentNamespace in help2Namespaces) + { + IHxRegPlugInList p = + (IHxRegPlugInList)currentNamespace.GetProperty(HxRegNamespacePropId.HxRegNamespacePlugInList); + foreach (IHxRegPlugIn plugin in p) + { + string currentName = (string)plugin.GetProperty(HxRegPlugInPropId.HxRegPlugInName); + if (string.Compare(currentName, pluginName) == 0) + { + namespaces.Add(currentNamespace.Name); + break; + } + } + } + } + catch (System.Runtime.InteropServices.COMException) + { + } + ReadOnlyCollection roNamespaces = new ReadOnlyCollection(namespaces); + return roNamespaces; + } + + public static string GetFirstMatchingNamespaceName(string matchingName) + { + HxRegistryWalkerClass registryWalker; + IHxRegNamespaceList help2Namespaces; + try + { + registryWalker = new HxRegistryWalkerClass(); + help2Namespaces = registryWalker.get_RegisteredNamespaceList(""); + } + catch (System.Runtime.InteropServices.COMException) + { + help2Namespaces = null; + registryWalker = null; + } + + if (registryWalker == null || help2Namespaces == null || help2Namespaces.Count == 0 || string.IsNullOrEmpty(matchingName)) + { + return string.Empty; + } + foreach (IHxRegNamespace currentNamespace in help2Namespaces) + { + if (NativeMethods.PathMatchSpec(currentNamespace.Name, matchingName)) + { + return currentNamespace.Name; + } + } + return help2Namespaces.ItemAt(1).Name; + } + } + + internal class NativeMethods + { + NativeMethods() + { + } + + #region PatchMatchSpec + [DllImport("shlwapi.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool PathMatchSpec(string pwszFile, string pwszSpec); + #endregion + } +} diff --git a/src/Tools/Help/source/HelperClasses/RegistrationClass.cs b/src/Tools/Help/source/HelperClasses/RegistrationClass.cs new file mode 100644 index 0000000000..1aec24d1cf --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/RegistrationClass.cs @@ -0,0 +1,332 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Globalization; + using System.IO; + using System.Xml; + using MSHelpServices; + + public class Help2RegisterClass : IDisposable + { + HxRegisterSessionClass registerSession = null; + IHxRegister register = null; + IHxFilters filters = null; + IHxPlugIn plugins = null; + + #region Constructor/Destructor + public Help2RegisterClass() + { + try + { + registerSession = new HxRegisterSessionClass(); + registerSession.CreateTransaction(""); + + register = (IHxRegister)registerSession.GetRegistrationObject(HxRegisterSession_InterfaceType.HxRegisterSession_IHxRegister); + filters = (IHxFilters)registerSession.GetRegistrationObject(HxRegisterSession_InterfaceType.HxRegisterSession_IHxFilters); + plugins = (IHxPlugIn)registerSession.GetRegistrationObject(HxRegisterSession_InterfaceType.HxRegisterSession_IHxPlugIn); + } + catch (System.Runtime.InteropServices.COMException) + { + } + } + + ~Help2RegisterClass() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (registerSession != null) + { + // PLEASE DO NOT CHANGE OR REMOVE THAT!!! + + registerSession.CommitTransaction(); + + // It's very important to close the connection to the Help 2.0 + // environment. Trust me. I cannot explain because I don't know + // anything about the Help 2.0 API. I was experimenting with the + // Help 2.0 system and I knocked it out so many times ... + } + } + } + #endregion + + private static string GetXmlContent(string collectionFile, string xmlNode) + { + if (string.IsNullOrEmpty(collectionFile) || string.IsNullOrEmpty(xmlNode)) + { + return string.Empty; + } + try + { + XmlDocument xmldoc = new XmlDocument(); + xmldoc.Load(collectionFile); + XmlNodeList n = xmldoc.SelectNodes + (string.Format(CultureInfo.InvariantCulture, "/HelpCollection/{0}/@File", xmlNode)); + + if (n.Count > 0) + { + return n.Item(0).InnerText; + } + } + catch (NullReferenceException) + { + } + return string.Empty; + } + + #region Register/Unregister + public bool RegisterNamespace(string namespaceName, string collectionFile) + { + return this.RegisterNamespace(namespaceName, collectionFile, string.Empty, true); + } + + public bool RegisterNamespace(string namespaceName, string collectionFile, string description) + { + return this.RegisterNamespace(namespaceName, collectionFile, description, true); + } + + public bool RegisterNamespace(string namespaceName, string collectionFile, string description, bool overwrite) + { + if (register == null || string.IsNullOrEmpty(namespaceName) || string.IsNullOrEmpty(collectionFile)) + { + return false; + } + try + { + // The default setting is to remove the namespace. But if you + // just want to add some new help documents or filters, you + // shouldn't remove it. + if(overwrite && register.IsNamespace(namespaceName)) + { + register.RemoveNamespace(namespaceName); + } + + // If the namespace doesn't exist, create it + if(!register.IsNamespace(namespaceName)) + { + register.RegisterNamespace(namespaceName, collectionFile, description); + } + return true; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public bool RemoveNamespace(string namespaceName) + { + if (register == null || string.IsNullOrEmpty(namespaceName)) + { + return false; + } + try + { + if(register.IsNamespace(namespaceName)) + { + register.RemoveNamespace(namespaceName); + } + + return true; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public bool RegisterHelpFile(string namespaceName, string helpFileId, int languageId, string hxsFile, + string hxiFile, string hxqFile, string hxrFile, int hxsMediaId, + int hxqMediaId, int hxrMediaId, int sampleMediaId) + { + if (register == null || + string.IsNullOrEmpty(namespaceName) || + string.IsNullOrEmpty(helpFileId) || + string.IsNullOrEmpty(hxsFile)) + { + return false; + } + try + { + if(register.IsNamespace(namespaceName)) + { + register.RegisterHelpFileSet(namespaceName, // Help 2.0 Collection Namespace + helpFileId, // internal Help document ID + languageId, // Language ID + hxsFile, // Help document + hxiFile, // external Help index + hxqFile, // merged query file + hxrFile, // combined attributes file + hxsMediaId, + hxqMediaId, + hxrMediaId, + sampleMediaId); + + // If you want to know something about those file types, I suggest you + // take a look at Microsoft's VSHIK documentation. + } + + return true; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public bool RemoveHelpFile(string namespaceName, string helpFileId, int languageId) + { + if (register == null || + string.IsNullOrEmpty(namespaceName) || + string.IsNullOrEmpty(helpFileId)) + { + return false; + } + try + { + if(register.IsNamespace(namespaceName)) + { + register.RemoveHelpFile(namespaceName, helpFileId, languageId); + } + + return true; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public bool RegisterFilter(string namespaceName, string filterName, string filterQuery) + { + if (register == null || + filters == null || + string.IsNullOrEmpty(namespaceName) || + string.IsNullOrEmpty(filterName)) + { + return false; + } + try + { + filters.SetNamespace(namespaceName); + filters.SetCollectionFiltersFlag(true); + filters.RegisterFilter(filterName, filterQuery); + } + catch (System.Runtime.InteropServices.COMException) + { + } + + // This function ALWAYS returns true. It's because an empty filter + // query raises an exception but the filter will be created. A good + // example is the known "(no filter)" filter. + // So, don't change it. + + return true; + } + + public bool RemoveFilter(string namespaceName, string filterName) + { + if (register == null || + filters == null || + string.IsNullOrEmpty(namespaceName) || + string.IsNullOrEmpty(filterName)) + { + return false; + } + try + { + filters.SetNamespace(namespaceName); + filters.SetCollectionFiltersFlag(true); + filters.RemoveFilter(filterName); + + return true; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + + public bool RegisterPlugin(string parentNamespace, string childNamespace) + { + return this.PluginAction(parentNamespace, childNamespace, true); + } + + public bool RemovePlugin(string parentNamespace, string childNamespace) + { + return this.PluginAction(parentNamespace, childNamespace, false); + } + + private bool PluginAction(string parentNamespace, string childNamespace, bool registerIt) + { + if (register == null || + plugins == null || + string.IsNullOrEmpty(parentNamespace) || + string.IsNullOrEmpty(childNamespace) || + !register.IsNamespace(parentNamespace) || + !register.IsNamespace(childNamespace)) + { + return false; + } + + // if you want to remove a plug-in, at least it should be there + if(!registerIt && !PluginSearch.PluginDoesExist(parentNamespace, childNamespace)) + { + return false; + } + + try + { + // unregister plug-in + if(!registerIt) + { + if(PluginSearch.PluginDoesExist(parentNamespace, childNamespace)) + { + plugins.RemoveHelpPlugIn(parentNamespace, "", childNamespace, "", ""); + return true; + } + } + + // (re)register plug-in + string path1 = string.Empty; + + // The function requires the names of the TOC files. I can take them from + // the collection level files (*.HxC) of the collections. + string parentToc = GetXmlContent(register.GetCollection(parentNamespace), "TOCDef"); + string childToc = GetXmlContent(register.GetCollection(childNamespace), "TOCDef"); + string attr = GetXmlContent(register.GetCollection(childNamespace), "AttributeDef"); + + if(!string.IsNullOrEmpty(attr)) + { + path1 = Path.Combine(Path.GetDirectoryName(register.GetCollection(childNamespace)), attr); + } + + if(registerIt && !string.IsNullOrEmpty(parentToc) && !string.IsNullOrEmpty(childToc)) + { + plugins.RegisterHelpPlugIn(parentNamespace, parentToc, childNamespace, childToc, path1, 0); + return true; + } + else return false; + } + catch (System.Runtime.InteropServices.COMException) + { + } + return false; + } + #endregion + } +} diff --git a/src/Tools/Help/source/HelperClasses/ResourcesHelper.cs b/src/Tools/Help/source/HelperClasses/ResourcesHelper.cs new file mode 100644 index 0000000000..622229c1fb --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/ResourcesHelper.cs @@ -0,0 +1,27 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Reflection; + using System.Resources; + + public sealed class ResourcesHelper + { + static ResourcesHelper instance = new ResourcesHelper(); + + public static string GetString(string keyName) + { + return instance.StringResourceHelper.GetString(keyName); + } + + ResourceManager StringResourceHelper; + + ResourcesHelper() + { + StringResourceHelper = new ResourceManager("Help2Register.String", GetType().Assembly); + } + } +} diff --git a/src/Tools/Help/source/HelperClasses/XmlHelperClass.cs b/src/Tools/Help/source/HelperClasses/XmlHelperClass.cs new file mode 100644 index 0000000000..0368b7d9cc --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/XmlHelperClass.cs @@ -0,0 +1,121 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Xml; + using System.Xml.XPath; + + public sealed class XmlHelperClass + { + XmlHelperClass() + { + } + + public static bool SetXmlStringAttributeValue(XPathNavigator parentNode, string valueName, string newValue) + { + if (parentNode == null || string.IsNullOrEmpty(valueName)) + { + return false; + } + try + { + XPathNavigator factory = parentNode.Clone(); + do + { + factory.MoveToFirstAttribute(); + + if (string.Compare(factory.Name, valueName) == 0) + { + factory.SetValue(newValue); + return true; + } + } + while (!factory.MoveToNextAttribute()); + + parentNode.CreateAttribute(string.Empty, + valueName, + string.Empty, + newValue); + return true; + } + catch (ArgumentNullException) + { + } + catch (InvalidOperationException) + { + } + return false; + } + + public static string GetXmlStringValue(XPathNavigator parentNode, string valueName) + { + if (parentNode == null || string.IsNullOrEmpty(valueName)) + { + return string.Empty; + } + try + { + XPathNavigator node = parentNode.SelectSingleNode(valueName); + return node.Value; + } + catch (NullReferenceException) + { + } + return string.Empty; + } + + public static int GetXmlIntValue(XPathNavigator parentNode, string valueName, int defaultValue) + { + if (parentNode == null || string.IsNullOrEmpty(valueName)) + { + return defaultValue; + } + try + { + XPathNavigator node = parentNode.SelectSingleNode(valueName); + return node.ValueAsInt; + } + catch (NullReferenceException) + { + } + catch (FormatException) + { + } + return defaultValue; + } + + public static bool GetXmlBoolValue(XPathNavigator parentNode, string valueName) + { + return GetXmlBoolValue(parentNode, valueName, false); + } + + public static bool GetXmlBoolValue(XPathNavigator parentNode, string valueName, bool emptyIsTrue) + { + if (parentNode == null || string.IsNullOrEmpty(valueName)) + { + return false; + } + bool result = false; + + try + { + XPathNavigator node = parentNode.SelectSingleNode(valueName); + if (emptyIsTrue) + { + result = (node == null || (node != null && node.Value == "yes" && string.IsNullOrEmpty(node.Value))); + } + else + { + result = (node != null && node.Value == "yes"); + } + } + catch (NullReferenceException) + { + } + return result; + } + } +} diff --git a/src/Tools/Help/source/HelperClasses/XmlValidatorClass.cs b/src/Tools/Help/source/HelperClasses/XmlValidatorClass.cs new file mode 100644 index 0000000000..7093b034b6 --- /dev/null +++ b/src/Tools/Help/source/HelperClasses/XmlValidatorClass.cs @@ -0,0 +1,50 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.HelperClasses +{ + using System; + using System.Reflection; + using System.IO; + using System.Xml; + using System.Xml.Schema; + + public sealed class XmlValidator + { + private static bool validationSuccess = true; + private static bool beQuiet; + private static string me = + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "register.xsd"); + + XmlValidator() + { + } + + public static bool XsdFileDoesExist + { + get { return File.Exists(me); } + } + + public static bool Validate(string xmlCommandFile, bool silentMode) + { + beQuiet = silentMode; + + XmlReaderSettings xsd = new XmlReaderSettings(); + xsd.Schemas.Add(ApplicationHelpers.Help2NamespaceUri, me); + xsd.ValidationType = ValidationType.Schema; + xsd.ValidationEventHandler += new ValidationEventHandler(ValidationCallback); + + XmlReader reader = XmlReader.Create(xmlCommandFile, xsd); + while(reader.Read()) { } + + return validationSuccess; + } + + private static void ValidationCallback(object sender, ValidationEventArgs e) + { + if(!beQuiet) Console.WriteLine(e.Message); + validationSuccess = false; + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/DocumentItemClass.cs b/src/Tools/Help/source/ItemClasses/DocumentItemClass.cs new file mode 100644 index 0000000000..2b54b2cad5 --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/DocumentItemClass.cs @@ -0,0 +1,102 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Globalization; + using System.Xml; + using System.Xml.XPath; + using HtmlHelp2Registration.HelperClasses; + + public class DocumentItemClass + { + private string id; + private string hxs; + private string hxi; + private string hxq; + private string hxr; + private int languageId; + private int hxsMediaId; + private int hxqMediaId; + private int hxrMediaId; + private int sampleMediaId; + + public DocumentItemClass(XPathNavigator rootFilenode) + { + if (rootFilenode == null) + { + throw new ArgumentNullException("rootFilenode"); + } + + this.id = XmlHelperClass.GetXmlStringValue(rootFilenode, "@Id"); + this.hxs = XmlHelperClass.GetXmlStringValue(rootFilenode, "@HxS"); + this.hxi = XmlHelperClass.GetXmlStringValue(rootFilenode, "@HxI"); + this.hxq = XmlHelperClass.GetXmlStringValue(rootFilenode, "@HxQ"); + this.hxr = XmlHelperClass.GetXmlStringValue(rootFilenode, "@HxR"); + this.languageId = XmlHelperClass.GetXmlIntValue(rootFilenode, "@LangId", 1033); + this.hxsMediaId = XmlHelperClass.GetXmlIntValue(rootFilenode, "@HxSMediaId", 0); + this.hxqMediaId = XmlHelperClass.GetXmlIntValue(rootFilenode, "@HxQMediaId", 0); + this.hxrMediaId = XmlHelperClass.GetXmlIntValue(rootFilenode, "@HxRMediaId", 0); + this.sampleMediaId = XmlHelperClass.GetXmlIntValue(rootFilenode, "@SampleMediaId", 0); + } + + #region Properties + public string Id + { + get { return this.id; } + } + + public string Hxs + { + get { return this.hxs; } + } + + public string Hxi + { + get{ return this.hxi; } + } + + public string Hxq + { + get { return this.hxq; } + } + + public string Hxr + { + get { return this.hxr; } + } + + public int LanguageId + { + get { return this.languageId; } + } + + public int HxsMediaId + { + get { return this.hxsMediaId; } + } + + public int HxqMediaId + { + get { return this.hxqMediaId; } + } + + public int HxrMediaId + { + get { return this.hxrMediaId; } + } + + public int SampleMediaId + { + get { return this.sampleMediaId; } + } + #endregion + + public override string ToString() + { + return String.Format(CultureInfo.InvariantCulture, "[Help 2.0 Document; {0}, {1}]", this.id, this.languageId); + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/FilterItemClass.cs b/src/Tools/Help/source/ItemClasses/FilterItemClass.cs new file mode 100644 index 0000000000..a592578c1c --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/FilterItemClass.cs @@ -0,0 +1,46 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Globalization; + using System.Xml; + using System.Xml.XPath; + using HtmlHelp2Registration.HelperClasses; + + public class FilterItemClass + { + private string name; + private string query; + + public FilterItemClass(XPathNavigator rootFilternode) + { + if (rootFilternode == null) + { + throw new ArgumentNullException("rootFilternode"); + } + + this.name = XmlHelperClass.GetXmlStringValue(rootFilternode, "@name"); + this.query = rootFilternode.Value; + } + + #region Properties + public string Name + { + get { return this.name; } + } + + public string Query + { + get { return this.query; } + } + #endregion + + public override string ToString() + { + return String.Format(CultureInfo.InvariantCulture, "[Help 2.0 Filter; {0} = {1}]", this.name, this.query); + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/ICommonItemClass.cs b/src/Tools/Help/source/ItemClasses/ICommonItemClass.cs new file mode 100644 index 0000000000..57d0b16d01 --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/ICommonItemClass.cs @@ -0,0 +1,12 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + public interface ICommonItemClass + { + void Register(); + void Unregister(); + } +} diff --git a/src/Tools/Help/source/ItemClasses/ItemEventHandling.cs b/src/Tools/Help/source/ItemClasses/ItemEventHandling.cs new file mode 100644 index 0000000000..091ceac694 --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/ItemEventHandling.cs @@ -0,0 +1,89 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + + public class CommonRegisterEventArgs : EventArgs + { + private readonly string name; + private readonly bool register = true; + + public CommonRegisterEventArgs(string name, bool register) + { + this.name = name; + this.register = register; + } + + public string Name + { + get { return this.name; } + } + + public bool Register + { + get { return this.register; } + } + } + + public class PluginRegisterEventArgs : EventArgs + { + private readonly string parent; + private readonly string child; + private readonly bool register = true; + + public PluginRegisterEventArgs(string parent, string child, bool register) + { + this.parent = parent; + this.child = child; + this.register = register; + } + + public string Parent + { + get { return this.parent; } + } + + public string Child + { + get { return this.child; } + } + + public bool Register + { + get { return this.register; } + } + } + + public class MergeNamespaceEventArgs : EventArgs + { + private readonly string name; + + public MergeNamespaceEventArgs(string name) + { + this.name = name; + } + + public string Name + { + get { return this.name; } + } + } + + public class LoggingEventArgs : EventArgs + { + private readonly string message; + + public LoggingEventArgs(string message) + { + this.message = message; + } + + public string Message + { + get { return this.message; } + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/NamespaceItemClass.cs b/src/Tools/Help/source/ItemClasses/NamespaceItemClass.cs new file mode 100644 index 0000000000..6dc5486623 --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/NamespaceItemClass.cs @@ -0,0 +1,152 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Globalization; + using System.IO; + using System.Xml; + using System.Xml.XPath; + using System.Xml.Serialization; + using HtmlHelp2Registration.HelperClasses; + + public class NamespaceItemClass + { + private string name; + private string description; + private string collection; + private bool update; + private bool merge = true; + private bool noremove = true; + private List documents = new List(); + private List filters = new List(); + private List plugins = new List(); + private ReadOnlyCollection connections = null; + + public NamespaceItemClass(XPathNavigator rootNode) + { + if (rootNode == null) + { + throw new ArgumentNullException("rootNode"); + } + + this.name = XmlHelperClass.GetXmlStringValue(rootNode, "@name"); + this.description = XmlHelperClass.GetXmlStringValue(rootNode, "@description"); + this.collection = XmlHelperClass.GetXmlStringValue(rootNode, "@file"); + this.update = XmlHelperClass.GetXmlBoolValue(rootNode, "@update"); + this.merge = XmlHelperClass.GetXmlBoolValue(rootNode, "@merge", true); + this.noremove = XmlHelperClass.GetXmlBoolValue(rootNode, "@noremove"); + this.connections = PluginSearch.FindPluginAsGenericList(this.name); + + this.Initialize(rootNode); + } + + void Initialize(XPathNavigator rootNode) + { + // get all related documents + XPathNodeIterator files = + rootNode.SelectChildren("file", ApplicationHelpers.Help2NamespaceUri); + while (files.MoveNext()) + { + this.documents.Add(new DocumentItemClass(files.Current)); + } + + // get all related filters + XPathNodeIterator filters = + rootNode.SelectChildren("filter", ApplicationHelpers.Help2NamespaceUri); + while (filters.MoveNext()) + { + this.filters.Add(new FilterItemClass(filters.Current)); + } + + // get all related plugins + XPathNodeIterator p = + rootNode.SelectChildren("plugin", ApplicationHelpers.Help2NamespaceUri); + while (p.MoveNext()) + { + XPathNodeIterator child = + p.Current.SelectChildren("child", ApplicationHelpers.Help2NamespaceUri); + while (child.MoveNext()) + { + this.plugins.Add(new PluginChildItem(child.Current)); + } + } + } + + #region Properties + public string Name + { + get { return this.name; } + } + + public string Description + { + get { return this.description; } + } + + public string CollectionLevelFile + { + get { return this.collection; } + } + + public bool ForceCreation + { + get { return !this.update; } + } + + public bool Merge + { + get { return this.merge; } + } + + public bool Remove + { + get { return !this.noremove; } + } + + public ReadOnlyCollection Documents + { + get + { + ReadOnlyCollection roDocuments = + new ReadOnlyCollection(this.documents); + return roDocuments; + } + } + + public ReadOnlyCollection Filters + { + get + { + ReadOnlyCollection roFilters = + new ReadOnlyCollection(this.filters); + return roFilters; + } + } + + public ReadOnlyCollection Plugins + { + get + { + ReadOnlyCollection roPlugins = + new ReadOnlyCollection(this.plugins); + return roPlugins; + } + } + + public ReadOnlyCollection ConnectedNamespaces + { + get { return this.connections; } + } + #endregion + + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "[Help 2.0 Namespace; {0}, {1}]", this.name, this.description); + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/NamespacesItemClass.cs b/src/Tools/Help/source/ItemClasses/NamespacesItemClass.cs new file mode 100644 index 0000000000..0cb3a35988 --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/NamespacesItemClass.cs @@ -0,0 +1,285 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Xml; + using System.Xml.Serialization; + using HtmlHelp2Registration.HelperClasses; + + public class NamespacesItemClass : ICommonItemClass + { + private List helpNamespaces = new List(); + private XmlDocument xmldoc = new XmlDocument(); + private XmlNamespaceManager xmlns; + private string xmlFilename = string.Empty; + private string xmlXpathSequence = string.Empty; + + #region Constructor + public NamespacesItemClass(string xmlFilename) : this(xmlFilename, string.Empty) + { + } + + public NamespacesItemClass(string xmlFilename, string xmlXpathSequence) + { + this.xmlFilename = xmlFilename; + this.xmlXpathSequence = xmlXpathSequence; + this.Initialize(); + } + #endregion + + void Initialize() + { + this.xmlns = new XmlNamespaceManager(this.xmldoc.NameTable); + this.xmlns.AddNamespace("help2", ApplicationHelpers.Help2NamespaceUri); + + this.xmldoc.Load(this.xmlFilename); + XmlNodeList nodes = this.xmldoc.SelectNodes + (string.Format(CultureInfo.InvariantCulture, "/help2:register/help2:namespace{0}", this.xmlXpathSequence), this.xmlns); + + foreach (XmlNode node in nodes) + { + this.helpNamespaces.Add(new NamespaceItemClass(node.CreateNavigator())); + } + } + + public void Register() + { + foreach (NamespaceItemClass helpNamespace in helpNamespaces) + { + if (string.IsNullOrEmpty(helpNamespace.Name) || + string.IsNullOrEmpty(helpNamespace.CollectionLevelFile) || + !File.Exists(helpNamespace.CollectionLevelFile)) + { + continue; + } + + using (Help2RegisterClass register = new Help2RegisterClass()) + { + // force Help 2.0 namespace creation + if (helpNamespace.ForceCreation) + { + OnLogProgress(new LoggingEventArgs(helpNamespace.ToString())); + OnRegisterOrRemoveNamespace(new CommonRegisterEventArgs(helpNamespace.Name, true)); + register.RegisterNamespace(helpNamespace.Name, + helpNamespace.CollectionLevelFile, + helpNamespace.Description); + } + + // register Help 2.0 documents + foreach (DocumentItemClass document in helpNamespace.Documents) + { + if (string.IsNullOrEmpty(document.Id) || + string.IsNullOrEmpty(document.Hxs) || + !File.Exists(document.Hxs)) + { + continue; + } + + OnLogProgress(new LoggingEventArgs(document.ToString())); + OnRegisterOrRemoveHelpDocument(new CommonRegisterEventArgs(document.Id, true)); + register.RegisterHelpFile(helpNamespace.Name, + document.Id, + document.LanguageId, + document.Hxs, + document.Hxi, + document.Hxq, + document.Hxr, + document.HxsMediaId, + document.HxqMediaId, + document.HxrMediaId, + document.SampleMediaId); + } + + // register Help 2.0 filters + foreach (FilterItemClass filter in helpNamespace.Filters) + { + if (string.IsNullOrEmpty(filter.Name)) + { + continue; + } + + OnLogProgress(new LoggingEventArgs(filter.ToString())); + OnRegisterOrRemoveFilter(new CommonRegisterEventArgs(filter.Name, true)); + register.RegisterFilter(helpNamespace.Name, filter.Name, filter.Query); + } + + // register Help 2.0 child plug-ins + foreach (PluginChildItem plugin in helpNamespace.Plugins) + { + if (string.IsNullOrEmpty(plugin.MatchingName)) + { + continue; + } + + OnLogProgress(new LoggingEventArgs(plugin.ToString())); + OnRegisterOrRemovePlugin(new PluginRegisterEventArgs(helpNamespace.Name, plugin.MatchingName, true)); + register.RegisterPlugin(helpNamespace.Name, plugin.MatchingName); + + if (string.Compare(plugin.Name, plugin.MatchingName) != 0) + { + this.PatchXmlNode(helpNamespace.Name, plugin.Name, plugin.MatchingName); + } + } + + // merge Help 2.0 namespace + if (helpNamespace.Merge) + { + OnLogProgress(new LoggingEventArgs(string.Format(CultureInfo.InvariantCulture, "[merging {0}]", helpNamespace.Name))); + OnNamespaceMerge(new MergeNamespaceEventArgs(helpNamespace.Name)); + MergeNamespace.CallMerge(helpNamespace.Name); + + foreach(string connectedNamespace in helpNamespace.ConnectedNamespaces) + { + OnLogProgress(new LoggingEventArgs(string.Format(CultureInfo.InvariantCulture, "[merging {0}]", connectedNamespace))); + OnNamespaceMerge(new MergeNamespaceEventArgs(connectedNamespace)); + MergeNamespace.CallMerge(connectedNamespace); + } + } + } + } + } + + public void Unregister() + { + foreach (NamespaceItemClass helpNamespace in helpNamespaces) + { + if (string.IsNullOrEmpty(helpNamespace.Name)) + { + continue; + } + + using (Help2RegisterClass register = new Help2RegisterClass()) + { + // remove this Help 2.0 namespace, if it is a plug-in + foreach (string connectedNamespace in helpNamespace.ConnectedNamespaces) + { + OnRegisterOrRemovePlugin(new PluginRegisterEventArgs(connectedNamespace, helpNamespace.Name, false)); + register.RemovePlugin(connectedNamespace, helpNamespace.Name); + + OnNamespaceMerge(new MergeNamespaceEventArgs(connectedNamespace)); + MergeNamespace.CallMerge(connectedNamespace); + } + + // remove this namespace's child plug-ins + foreach (PluginChildItem plugin in helpNamespace.Plugins) + { + OnLogProgress(new LoggingEventArgs(plugin.ToString())); + OnRegisterOrRemovePlugin(new PluginRegisterEventArgs(helpNamespace.Name, plugin.MatchingName, false)); + register.RemovePlugin(helpNamespace.Name, plugin.MatchingName); + } + + // remove this namespace's filters + foreach (FilterItemClass filter in helpNamespace.Filters) + { + OnLogProgress(new LoggingEventArgs(filter.ToString())); + OnRegisterOrRemoveFilter(new CommonRegisterEventArgs(filter.Name, false)); + register.RemoveFilter(helpNamespace.Name, filter.Name); + } + + // remove this namespace's documents + foreach (DocumentItemClass document in helpNamespace.Documents) + { + OnLogProgress(new LoggingEventArgs(document.ToString())); + OnRegisterOrRemoveHelpDocument(new CommonRegisterEventArgs(document.Id, false)); + register.RemoveHelpFile(helpNamespace.Name, document.Id, document.LanguageId); + } + + // remove this namespace, ... + if (helpNamespace.Remove) + { + OnRegisterOrRemoveNamespace(new CommonRegisterEventArgs(helpNamespace.Name, false)); + register.RemoveNamespace(helpNamespace.Name); + } + // ... or just (re)merge it + else + { + OnNamespaceMerge(new MergeNamespaceEventArgs(helpNamespace.Name)); + MergeNamespace.CallMerge(helpNamespace.Name); + } + } + } + } + + void PatchXmlNode(string namespaceName, string pluginName, string matchingName) + { + if (this.xmldoc == null || + string.IsNullOrEmpty(namespaceName) || + string.IsNullOrEmpty(pluginName) || + string.IsNullOrEmpty(matchingName)) + { + return; + } + + XmlNode node = xmldoc.SelectSingleNode + (string.Format(CultureInfo.InvariantCulture, + "/help2:register/help2:namespace[@name=\"{0}\"]/help2:plugin/help2:child[@name=\"{1}\"]", + namespaceName, pluginName), this.xmlns); + XmlHelperClass.SetXmlStringAttributeValue(node.CreateNavigator(), "name", matchingName); + xmldoc.Save(this.xmlFilename); + } + + #region Events + public event EventHandler RegisterOrRemoveNamespace; + public event EventHandler RegisterOrRemoveHelpDocument; + public event EventHandler RegisterOrRemoveFilter; + public event EventHandler RegisterOrRemovePlugin; + public event EventHandler NamespaceMerge; + public event EventHandler LogProgress; + + private void OnRegisterOrRemoveNamespace(CommonRegisterEventArgs e) + { + if (RegisterOrRemoveNamespace != null) + { + RegisterOrRemoveNamespace(null, e); + } + } + + private void OnRegisterOrRemoveHelpDocument(CommonRegisterEventArgs e) + { + if (RegisterOrRemoveHelpDocument != null) + { + RegisterOrRemoveHelpDocument(null, e); + } + } + + private void OnRegisterOrRemoveFilter(CommonRegisterEventArgs e) + { + if (RegisterOrRemoveFilter != null) + { + RegisterOrRemoveFilter(null, e); + } + } + + private void OnRegisterOrRemovePlugin(PluginRegisterEventArgs e) + { + if (RegisterOrRemovePlugin != null) + { + RegisterOrRemovePlugin(null, e); + } + } + + private void OnNamespaceMerge(MergeNamespaceEventArgs e) + { + if (NamespaceMerge != null) + { + NamespaceMerge(null, e); + } + } + + private void OnLogProgress(LoggingEventArgs e) + { + if (LogProgress != null) + { + LogProgress(null, e); + } + } + #endregion + } +} diff --git a/src/Tools/Help/source/ItemClasses/PluginItemClass.cs b/src/Tools/Help/source/ItemClasses/PluginItemClass.cs new file mode 100644 index 0000000000..2e777c216d --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/PluginItemClass.cs @@ -0,0 +1,115 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Globalization; + using System.Collections.Generic; + using System.Xml; + using System.Xml.XPath; + using HtmlHelp2Registration.HelperClasses; + + public class PluginParentItem + { + private string realName; + private string matchingName; + private bool merge; + private List children = new List(); + + public PluginParentItem(XPathNavigator pluginRootnode) + { + if (pluginRootnode == null) + { + throw new ArgumentNullException("pluginRootnode"); + } + this.realName = XmlHelperClass.GetXmlStringValue(pluginRootnode, "@parent"); + this.matchingName = PluginSearch.GetFirstMatchingNamespaceName(this.realName); + this.merge = XmlHelperClass.GetXmlBoolValue(pluginRootnode, "@merge", true); + string childName = XmlHelperClass.GetXmlStringValue(pluginRootnode, "@child"); + + if (!string.IsNullOrEmpty(childName)) + { + this.children.Add(new PluginChildItem(childName)); + } + else + { + XPathNodeIterator pChild = + pluginRootnode.SelectChildren("child", ApplicationHelpers.Help2NamespaceUri); + while (pChild.MoveNext()) + { + this.children.Add(new PluginChildItem(pChild.Current)); + } + } + } + + #region Properties + public string Name + { + get { return this.realName; } + } + + public string MatchingName + { + get { return this.matchingName; } + } + + public bool Merge + { + get { return this.merge; } + } + #endregion + + public System.Collections.IEnumerator GetEnumerator() + { + foreach (PluginChildItem child in this.children) + { + yield return child; + } + } + } + + public class PluginChildItem + { + private string realName; + private string matchingName; + + public PluginChildItem(XPathNavigator pluginRootnode) + { + if (pluginRootnode == null) + { + throw new ArgumentNullException("pluginRootnode"); + } + this.realName = XmlHelperClass.GetXmlStringValue(pluginRootnode, "@name"); + this.matchingName = PluginSearch.GetFirstMatchingNamespaceName(this.realName); + } + + public PluginChildItem(string childName) + { + if (string.IsNullOrEmpty(childName)) + { + throw new ArgumentNullException("childName"); + } + this.realName = childName; + this.matchingName = PluginSearch.GetFirstMatchingNamespaceName(this.realName); + } + + #region Properties + public string Name + { + get { return this.realName; } + } + + public string MatchingName + { + get { return this.matchingName; } + } + #endregion + + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "[Help 2.0 Plug-in; {0}]", this.matchingName); + } + } +} diff --git a/src/Tools/Help/source/ItemClasses/PluginsItemClass.cs b/src/Tools/Help/source/ItemClasses/PluginsItemClass.cs new file mode 100644 index 0000000000..6709b6ed1b --- /dev/null +++ b/src/Tools/Help/source/ItemClasses/PluginsItemClass.cs @@ -0,0 +1,186 @@ +// +// Help 2.0 Registration Utility +// Copyright (c) 2005 Mathias Simmack. All rights reserved. +// +namespace HtmlHelp2Registration.ItemClasses +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Xml; + using System.Xml.XPath; + using HtmlHelp2Registration.HelperClasses; + + public class PluginsItemClass : ICommonItemClass + { + private List plugins = new List(); + private XmlDocument xmldoc = new XmlDocument(); + private XmlNamespaceManager xmlns; + private string xmlFilename = string.Empty; + private string xmlXpathSequence = string.Empty; + + #region Constructor + public PluginsItemClass(string xmlFilename) : this(xmlFilename, string.Empty) + { + } + + public PluginsItemClass(string xmlFilename, string xmlXpathSequence) + { + this.xmlFilename = xmlFilename; + this.xmlXpathSequence = xmlXpathSequence; + this.Initialize(); + } + #endregion + + void Initialize() + { + this.xmlns = new XmlNamespaceManager(this.xmldoc.NameTable); + this.xmlns.AddNamespace("help2", ApplicationHelpers.Help2NamespaceUri); + + this.xmldoc.Load(this.xmlFilename); + XmlNodeList nodes = this.xmldoc.SelectNodes + (string.Format(CultureInfo.InvariantCulture, "/help2:register/help2:plugin{0}", this.xmlXpathSequence), this.xmlns); + + foreach (XmlNode node in nodes) + { + this.plugins.Add(new PluginParentItem(node.CreateNavigator())); + } + } + + public void Register() + { + foreach (PluginParentItem plugin in this.plugins) + { + if (string.IsNullOrEmpty(plugin.MatchingName)) + { + continue; + } + + using (Help2RegisterClass register = new Help2RegisterClass()) + { + foreach (PluginChildItem child in plugin) + { + if (string.IsNullOrEmpty(child.MatchingName)) + { + continue; + } + + OnRegisterOrRemovePlugin(new PluginRegisterEventArgs(plugin.MatchingName, child.MatchingName, true)); + register.RegisterPlugin(plugin.MatchingName, child.MatchingName); + + if (string.Compare(plugin.Name, plugin.MatchingName) != 0) + { + this.PatchParentXmlNode(plugin.Name, plugin.MatchingName); + } + if (string.Compare(child.Name, child.MatchingName) != 0) + { + this.PatchChildXmlNode(plugin.Name, child.Name, child.MatchingName); + } + } + + if (plugin.Merge) + { + OnNamespaceMerge(new MergeNamespaceEventArgs(plugin.MatchingName)); + MergeNamespace.CallMerge(plugin.MatchingName); + } + } + } + } + + public void Unregister() + { + foreach (PluginParentItem plugin in this.plugins) + { + if (string.IsNullOrEmpty(plugin.MatchingName)) + { + continue; + } + + using (Help2RegisterClass register = new Help2RegisterClass()) + { + foreach (PluginChildItem child in plugin) + { + if (string.IsNullOrEmpty(child.MatchingName)) + { + continue; + } + + OnRegisterOrRemovePlugin(new PluginRegisterEventArgs(plugin.MatchingName, child.MatchingName, false)); + register.RemovePlugin(plugin.MatchingName, child.MatchingName); + } + + if (plugin.Merge) + { + OnNamespaceMerge(new MergeNamespaceEventArgs(plugin.MatchingName)); + MergeNamespace.CallMerge(plugin.MatchingName); + } + } + } + } + + private void PatchParentXmlNode(string realParentName, string matchingParentName) + { + if (this.xmldoc == null || + string.IsNullOrEmpty(realParentName) || + string.IsNullOrEmpty(matchingParentName)) + { + return; + } + + XmlNode node = this.xmldoc.SelectSingleNode + (string.Format(CultureInfo.InvariantCulture, "/register/plugin[@parent=\"{0}\"]", realParentName)); + XmlHelperClass.SetXmlStringAttributeValue(node.CreateNavigator(), "parent", matchingParentName); + this.xmldoc.Save(this.xmlFilename); + } + + private void PatchChildXmlNode(string realParentName, string realChildName, string matchingChildName) + { + if (this.xmldoc == null || + string.IsNullOrEmpty(realParentName) || + string.IsNullOrEmpty(realChildName) || + string.IsNullOrEmpty(matchingChildName)) + { + return; + } + + XmlNode node = this.xmldoc.SelectSingleNode + (string.Format(CultureInfo.InvariantCulture, "/register/plugin[@parent=\"{0}\"]", realParentName)); + if(node != null) + { + string childName = XmlHelperClass.GetXmlStringValue(node.CreateNavigator(), "@child"); + if(childName.Length > 0 && String.Compare(childName, realChildName) == 0) + { + XmlHelperClass.SetXmlStringAttributeValue(node.CreateNavigator(), "child", matchingChildName); + } + else + { + XmlNode child = node.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "child[@name=\"{0}\"]", realChildName)); + XmlHelperClass.SetXmlStringAttributeValue(child.CreateNavigator(), "name", matchingChildName); + } + this.xmldoc.Save(this.xmlFilename); + } + } + + #region Events + public event EventHandler RegisterOrRemovePlugin; + public event EventHandler NamespaceMerge; + + private void OnRegisterOrRemovePlugin(PluginRegisterEventArgs e) + { + if (RegisterOrRemovePlugin != null) + { + RegisterOrRemovePlugin(null, e); + } + } + + private void OnNamespaceMerge(MergeNamespaceEventArgs e) + { + if (NamespaceMerge != null) + { + NamespaceMerge(null, e); + } + } + #endregion + } +} diff --git a/src/Tools/Help/source/MSHelpServices.dll b/src/Tools/Help/source/MSHelpServices.dll new file mode 100644 index 0000000000000000000000000000000000000000..aa890731f410f24fad2beab638fc0b4ded394649 GIT binary patch literal 45056 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