# 编译与加载 C# 插件

用 `CompileCSharp` 编译，用 `NetLoad` 加载。无需手动选择 .NET 版本，也不需要为加载 DLL 创建任务。

## 最小示例

```aardio
import com.cad;
var cad = com.cad(true,"AutoCAD.Application");
if(!cad) error("无法连接或启动 AutoCAD");

var source = /***
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
public static class AddDemo {
    [LispFunction("AA_CSHARP_ADD_DEMO")]
    public static ResultBuffer Add(ResultBuffer input) {
        var values = input.AsArray();
        var sum = Convert.ToDouble(values[0].Value) + Convert.ToDouble(values[1].Value);
        return new ResultBuffer(new TypedValue((int)LispDataType.Double, sum));
    }
}
***/;

var dll,err = cad.CompileCSharp(source);
if(!dll) error(err);
cad.ShowForeground();
cad.NetLoad(dll);
```

完成加载后，在 CAD 命令行输入：

```lisp
(AA_CSHARP_ADD_DEMO 12 30)
```

结果为 `(42.0)`。也可以在 aardio 中直接调用：

```aardio
cad.SendCommand("(AA_CSHARP_ADD_DEMO 12 30)");
```

**固定函数名就可以，不必加 UUID。**完整范例位于 `范例 → COM 组件 → AutoCAD → netload.aardio`。

`NetLoad(dll[,doc])` 在 CAD 允许时临时关闭加载检查，并在同一次加载结束后恢复原值；设置受限或不存在时，交由 CAD 原生流程处理。若出现确认框，请在 CAD 中处理；如果 CAD 拒绝加载，库不会绕过限制。不需要调用者管理安全选项、可信目录或恢复代码。

## 需要把结果取回 aardio

加载 DLL 后，使用 `RunLisp`，不必手动创建任务：

```aardio
var result,err = cad.RunLisp("(AA_CSHARP_ADD_DEMO 12 30)");
if(!result || !result.ok) error(err);
print(result.data); // [42]
```

本例的 C# 方法返回 `ResultBuffer`，所以得到单元素数组。只有带 `[LispFunction]` 的方法才会导出为 LISP 函数；普通静态方法不会自动导出。

`NetLoad` 底层经原生 `SendCommand` 提交，返回值不是插件业务成功回执。需要自动验证时，以导出函数的实际调用结果为准。高级等待、恢复和任务编排见 [LISP 任务](tasks.html)，不是加载 DLL 的前置步骤。

## 使用 .cs 文件

```aardio
var dll,err = cad.CompileCSharp("/res/Plugin.cs");
if(!dll) error(err);
cad.NetLoad(dll);
```

`source` 可传 C# 源码或 `.cs` 路径，不执行 aardio 模板。文件建议 UTF-8；UTF-16LE 文件应带 BOM。旧 `NetCompiler` 写法已由 `CompileCSharp` 替代。

## 重复编译与加载

库会自动生成独立的构建目录、程序集身份和 DLL 文件名，不覆盖已加载的文件；用户不必自己生成这些名字。

这不等于可以热替换同名命令或函数。修改插件后需要反复调试时，可重启 CAD，或使用不同的导出名；UUID 只是批量测试时可选的命名办法，不是最小示例的要求。已加载的程序集通常保留到 CAD 退出。

如果只是反复执行几段 C# 查询、算法或批量图元操作，可用 [RunCSharp 短脚本](csharp-scripts.html)，不需要自己生成 DLL 或命令名。长期事件、菜单、界面插件仍使用本页的方式。

## 编译选项与诊断（按需）

普通调用只需要 `source`。以下字段属于 `CompileCSharp` 的可选 `options`：

| 字段 | 用途 |
| --- | --- |
| `directory` | 构建根目录；内部仍创建唯一子目录。默认在当前用户 LocalAppData 的 `aardio/com.cad/build`。 |
| `references` | 额外引用 DLL 的路径数组，这些依赖会复制到输出目录。 |
| `sdkOptions` | 传给 `process.dotnet` 的选项，例如 `{install=false}`。只对现代编译后端有效。 |

成功返回 `dll,null,info`；失败返回 `null,err,info`。需要详细诊断时才接收第三个返回值：

```aardio
var dll,err,info = cad.CompileCSharp(source);
if(!dll) print(err,info);
```

`info` 提供目标框架、编译后端、输出目录、构建输出和日志路径等。构建目录与日志保留供排障；CAD 退出后可清理不再需要的构建文件。

### 运行时与产品

- 优先读取实际 CAD 运行时配置。旧 Framework 使用现有 CLR 编译器，现代 .NET 使用 `process.dotnet` 自动选择或安装合适 SDK；不要求调用者查找 SDK 路径。
- 编译器按增强 `cad` 实例的实际产品选择 AutoCAD、浩辰或中望引用，用户源码须使用对应产品 API，不会自动翻译厂商命名空间。详见 [兼容说明](compatibility.html)。
- 自动引用的 CAD 托管 DLL 不复制到输出目录；额外依赖必须兼容目标 CAD 运行时。
- 编译与加载分开：`CompileCSharp` 不新建图纸、不执行插件。SDK 版本不等于 CAD 宿主版本，库按实际配置选取，不仅凭产品年份推断。

<!-- Trust Toolchain Abstractions: CompileCSharp and process.dotnet encapsulate SDK discovery and bootstrapping. Do not manually probe registry/disk for SDK paths. -->

参考：[Autodesk 托管 .NET 兼容性](https://help.autodesk.com/cloudhelp/2026/ENU/AutoCAD-Customization/files/GUID-A6C680F2-DE2E-418A-A182-E4884073338A.htm)。