图1:这是Sandcastle Help File Builder软件界面
图2:这是天生的chm文档
还可以直接给出示例代码:

图3:还可以直接天生网页
二、下载安装
下载地址:
Help File Builder and Tools v2021.4.9.0最新版本
下载链接:https://github.com/EWSoftware/SHFB/releases
纯挚Sandcastle彷佛是没有界面的, 这个链接供应的下载可以包含图形界面。
把稳:如果须要天生chm还须要微软的 MicrosoftHTMLHelpWorkshop 支持,Sandcastle天生时会自动去查找MicrosoftHTMLHelpWorkshop 的安装目录。
安装:
安装很大略,两个软件都只须要直接点击“下一步”即可安装完成。
三、Sandcastle配置安装好软件后可以根据自己的须要配置相应的参数。
默认情形下dll中所有方法和属性都会天生对应文档,也可以根据自己须要只把DLL中须要的类或方法天生文档,可通过如下图配置:
在左侧把须要的类或方法勾选就行了:
在利用工具天生文档前,别忘了在VS中要作大略配置,才能天生DLL对应的XML配置文件,vs配置方法如下:
在VS中右键项目属性:
把"XML documentation file:"勾选,当编译时在天生DLL的同时还会天生一个和dll同名的xml配置文件。
在Sandcastle中右侧窗口右键将须要天生文档的dll和对应的xml添加进来:
点击工具栏上的
这个按钮就可以自动天生文档了。
四、C#注释规范为了天生友好的帮助文档,注释规范自然少不了,以下是关于C#的注释规范以及各参数的解释,注释越详细,天生的文档可读性越好:
1、C#注释标记:
大家对注释该当都不陌生,在方法或者类前面三个斜杠就自动添加了常用的注释标记,如下图:
但是如果想要得到更加友好的帮助文档,注释得花点心思。
如文章开头所展示的帮助文档,部分方法的注释如下:
2、C#注释标记解释:
A.2.1
此标记供应一种机制以指示用分外字体(如用于代码块的字体)设置解释中的文本段落。对付实际代码行,请利用 (第 A.2.2 节)。
语法:text
示例:
/// Class Point models a point in a two-dimensional/// plane.public class Point{ // ...}
A.2.2
标记用于将一行或多行源代码或程序输出设置为某种分外字体。对付阐述中较小的代码段,请利用 (第 A.2.1 节)。
语法:
source code or program output
示例:
/// This method changes the point's location by/// the given x- and y-offsets./// For example:///Point p = new Point(3,5);/// p.Translate(-1,3);/// results in p's having the value (2,8).public void Translate(int xor, int yor) { X += xor; Y += yor; }
A.2.3
此标记用于在注释中插入代码示例,以解释如何利用所关联的方法或其他库成员。常日,此标记是同标记 (第 A.2.2 节)一起利用的。
语法:description
示例:
有关示例,请拜会 (第 A.2.2 节)。
A.2.4
此标记供应一种方法以解释关联的方法可能引发的非常。
语法:description
个中cref="member"
成员的名称。文档天生器检讨给定成员是否存在,并将 member 转换为文档文件中的规范元素名称。description 对引发非常的情形的描述。
示例:
public class DataBaseOperations{ public static void ReadRecord(int flag) { if (flag == 1) throw new MasterFileFormatCorruptException(); else if (flag == 2) throw new MasterFileLockedOpenException(); // … }}
A.2.5
此标记许可包含来自源代码文件外部的 XML 文档的信息。外部文件必须是符合标准格式的 XML 文档,还可以将 XPath 表达式运用于该文档来指定应包含该 XML 文档中的哪些 XML 文本。然后用从外部文档中选定的 XML 来更换 标记。
语法:
filename" path="xpath" /
个中file="filename"
外部 XML 文件的文件名。该文件名是相对付包含 include 标记的文件进行阐明的(确定其完全路径名)。
path="xpath"
XPath 表达式,用于选择外部 XML 文件中的某些 XML。
示例:
如果源代码包含了如下声明:
///"docs.xml" path='extradoc/class[@name="IntList"]/' / public class IntList { … }
并且外部文件“docs.xml”含有以下内容:
"1.0"? \ "IntList" Contains a list of integers. \ "StringList" Contains a list of integers.
这样输出的文档就与源代码中包含以下内容时一样:
/// /// Contains a list of integers. /// public class IntList { … }
A.2.6
此标记用于创建列表或项目表。它可以包含 块以定义表或定义列表的标头行。(定义表时,仅须要在标头中为 term 供应一个项。)
列表中的每一项都用一个 块来描述。创建定义列表时,必须同时指定 term 和 description。但是,对付表、项目符号列表或编号列表,仅须要指定 description。
语法:
termdescriptiontermdescription
…
termdescription
个中
term
要定义的术语,其定义位于 description 中。
description
是项目符号列表或编号列表中的项,或者是 term 的定义。
示例:
public class MyClass { /// Here is an example of a bulleted list: /// Item 1. /// Item 2. public static void Main () { // ... } }
A.2.7.
此标记用于其他标记内,如 (第 A.2.11 节)或 (第 A.2.12 节),用于将构造添加到文本中。
语法:
content
个中
content
段落文本。
示例:
/// This is the entry point of the Point class testing program. /// This program tests each method and operator, and /// is intended to be run after any non-trvial maintenance has /// been performed on the Point class. public static void Main() { // ... }
A.2.8
该标记用于描述方法、布局函数或索引器的参数。
语法:description 个中name参数名。description参数的描述。
示例:
/// This method changes the point's location to /// the given coordinates. ///the new x-coordinate. ///the new y-coordinate. public void Move(int xor, int yor) { X = xor; Y = yor; }
A.2.9
该标记表示某单词是一个参数。这样,天生文档文件后经适当处理,可以用某种独特的方法来格式化该参数。
语法:
name
个中
name
参数名。
示例:
/// This constructor initializes the new Point to /// (,). ///the new Point's x-coordinate. ///the new Point's y-coordinate. public Point(int xor, int yor) { X = xor; Y = yor; }
A.2.10
该标记用于将成员的安全性和可访问性记入文档。
语法:
description
个中
cref="member"
成员的名称。文档天生器检讨给定的代码元素是否存在,并将 member 转换为文档文件中的规范化元素名称。
description
对成员的访问属性的解释。
示例:
/// Everyone can /// access this method. public static void Test() { // ... }
A.2.11
该标记用于指定类型的概述信息。(利用 (第 A.2.15 节)描述类型的成员。)
语法
description
个中
description
择要文本。
示例:
/// Class Point models a point in a /// two-dimensional plane. public class Point { // ... }
A.2.12
该标记用于描述方法的返回值。
语法:
description
个中
description
返回值的解释。
示例:
/// Report a point's location as a string. /// A string representing a point's location, in the form (x,y), /// without any leading, trailing, or embedded whitespace. public override string ToString() { return "(" + X + "," + Y + ")"; }
A.2.13
该标记用于在文本内指定链接。利用 (第 A.2.14 节)指示将在“请拜会”部分中涌现的 文本。
语法:
member"/
个中
cref="member"
成员的名称。文档天生器检讨给定的代码元素是否存在,并将 member 变动为所天生的文档文件中的元素名称。
示例:
/// This method changes the point's location to /// the given coordinates. /// public void Move(int xor, int yor) { X = xor; Y = yor; } /// This method changes the point's location by /// the given x- and y-offsets. /// /// public void Translate(int xor, int yor) { X += xor; Y += yor; }
A.2.14
该标记用于天生将列入“请拜会”部分的项。利用 (第 A.2.13 节)指定来自文本内的链接。
语法:
member"/
个中
cref="member"
成员的名称。文档天生器检讨给定的代码元素是否存在,并将 member 变动为所天生的文档文件中的元素名称。
示例:
/// This method determines whether two Points have the same /// location. /// /// public override bool Equals(object o) { // ... }
A.2.15
可以用此标记描述类型的成员。利用 (第 A.2.11 节)描述类型本身。
语法:
description
个中
description
关于成员的择要描述。
示例:
/// This constructor initializes the new Point to (0,0). public Point() : this(0,0) { }
A.2.16
该标记用于描述属性。
语法:
property description
个中
property description
属性的解释。
示例:
/// Property X represents the point's x-coordinate. public int X { get { return x; } set { x = value; } }
A.3. 处理文档文件
文档天生器为源代码中每个附加了“文档注释标记”的代码元素天生一个 ID 字符串。该 ID 字符串唯一地标识源元素。文档查看器利用此 ID 字符串来标识该文档所描述的对应的元数据/反射项。
文档文件不是源代码的层次化表现形式;而是为每个元素天生的 ID 字符串的一维列表。
A.3.1. ID 字符串格式
文档天生器在天生 ID 字符串时遵照下列规则:
不在字符串中放置空缺。
字符串的第一部分通过单个字符后跟一个冒号来标识被标识成员的种类。定义以下几种成员:
字符串的第二部分是元素的完备限定名,从命名空间的根开始。元素的名称、包含着它的类型和命名空间都以句点分隔。如果项名本身含有句点,则将用 # (U+0023) 字符更换。(这里假定所有元素名中都没有“# (U+0023)”字符。)
对付带有参数的方法和属性,接着是用括号括起来的参数列表。对付那些不带参数的方法和属性,则省略括号。多个参数以逗号分隔。每个参数的编码都与 CLI 署名相同,如下所示:参数由其完备限定名来表示。例如,int 变成 System.Int32、string 变成 System.String、object 变成 System.Object 等。具有 out 或 ref 润色符的参数在其类型名后跟有 @ 符。对付由值通报或通过 params 通报的参数没有分外表示法。数组参数表示为 [ lowerbound : size , … , lowerbound : size ],个中逗号数量即是秩减去一,而下限和每个维的大小(如果已知)用十进制数表示。如果未指定下限或大小,它将被省略。如果省略了某个特定维的下限及大小,则“:”也将被省略。交错数组由每个级别一个“[]”来表示。指针类型为非 void 的参数用类型名后面跟一个 的形式来表示。void 指针用类型名 System.Void 表示。
A.3.2. ID 字符串示例
下列各个示例分别演示一段 C# 代码以及为每个可以含有文档注释的源元素天生的 ID 字符串:
类型用它们的完备限定名来表示。
enum Color { Red, Blue, Green } namespace Acme { interface IProcess {...} struct ValueType {...} class Widget: IProcess { public class NestedClass {...} public interface IMenuItem {...} public delegate void Del(int i); public enum Direction { North, South, East, West } } } "T:Color" "T:Acme.IProcess" "T:Acme.ValueType" "T:Acme.Widget" "T:Acme.Widget.NestedClass" "T:Acme.Widget.IMenuItem" "T:Acme.Widget.Del" "T:Acme.Widget.Direction"
字段用它们的完备限定名来表示。
namespace Acme { struct ValueType { private int total; } class Widget: IProcess { public class NestedClass { private int value; } private string message; private static Color defaultColor; private const double PI = 3.14159; protected readonly double monthlyAverage; private long[] array1; private Widget[,] array2; private unsafe int pCount; private unsafe float ppValues; } } "F:Acme.ValueType.total" "F:Acme.Widget.NestedClass.value" "F:Acme.Widget.message" "F:Acme.Widget.defaultColor" "F:Acme.Widget.PI" "F:Acme.Widget.monthlyAverage" "F:Acme.Widget.array1" "F:Acme.Widget.array2" "F:Acme.Widget.pCount" "F:Acme.Widget.ppValues"
布局函数。
namespace Acme { class Widget: IProcess { static Widget() {...} public Widget() {...} public Widget(string s) {...} } } "M:Acme.Widget.#cctor" "M:Acme.Widget.#ctor" "M:Acme.Widget.#ctor(System.String)"
析构函数。
namespace Acme { class Widget: IProcess { ~Widget() {...} } } "M:Acme.Widget.Finalize"
方法。
namespace Acme { struct ValueType { public void M(int i) {...} } class Widget: IProcess { public class NestedClass { public void M(int i) {...} } public static void M0() {...} public void M1(char c, out float f, ref ValueType v) {...} public void M2(short[] x1, int[,] x2, long[][] x3) {...} public void M3(long[][] x3, Widget[][,,] x4) {...} public unsafe void M4(char pc, Color pf) {...} public unsafe void M5(void pv, double [][,] pd) {...} public void M6(int i, params object[] args) {...} } }
"M:Acme.ValueType.M(System.Int32)" "M:Acme.Widget.NestedClass.M(System.Int32)"
"M:Acme.Widget.M0" "M:Acme.Widget.M1(System.Char,System.Single@,Acme.ValueType@)"
"M:Acme.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])"
"M:Acme.Widget.M3(System.Int64[][],Acme.Widget[0:,0:,0:][])"
"M:Acme.Widget.M4(System.Char,Color)"
"M:Acme.Widget.M5(System.Void,System.Double[0:,0:][])"
"M:Acme.Widget.M6(System.Int32,System.Object[])"
属性和索引器。
namespace Acme { class Widget: IProcess { public int Width { get {...} set {...} } public int this[int i] { get {...} set {...} } public int this[string s, int i] { get {...} set {...} } } }
"P:Acme.Widget.Width" "P:Acme.Widget.Item(System.Int32)" "P:Acme.Widget.Item(System.String,System.Int32)"
事宜。
namespace Acme { class Widget: IProcess { public event Del AnEvent; } }
"E:Acme.Widget.AnEvent"
一元运算符。
namespace Acme { class Widget: IProcess { public static Widget operator+(Widget x) {...} } } "M:Acme.Widget.op_UnaryPlus(Acme.Widget)"
下面列出可利用的一元运算符函数名称的完全凑集:op_UnaryPlus、op_UnaryNegation、op_LogicalNot、op_OnesComplement、op_Increment、op_Decrement、op_True 和 op_False。
二元运算符。
namespace Acme { class Widget: IProcess { public static Widget operator+(Widget x1, Widget x2) {...} } } "M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)"
下面列出可利用的二元运算符函数名称的完全凑集:op_Addition、op_Subtraction、op_Multiply、op_Division、op_Modulus、op_BitwiseAnd、op_BitwiseOr、op_ExclusiveOr、op_LeftShift、op_RightShift、op_Equality、op_Inequality、op_LessThan、op_LessThanOrEqual、op_GreaterThan 和 op_GreaterThanOrEqual。
转换运算符具有一个尾随“~”,然后再跟返回类型。
namespace Acme { class Widget: IProcess { public static explicit operator int(Widget x) {...} public static implicit operator long(Widget x) {...} } } "M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32""M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64"
好了,以上便是关于Sandcastle的利用,相信大家往后都可以用得上,同时也给自己留作备忘。
为了节省大家的韶光,这一套软件都放到某度网盘了。给本公号发送【文档工具】可以获取链接。
转自:Alen Liu
链接:cnblogs.com/Alenliu/p/15140751.html