关于 acad-dotnet
acad-dotnet 是用于端到端创建 AutoCAD .NET 插件项目的 Agent Skill,面向开发 AutoCAD、Civil 3D 或 Plant 3D 插件的开发者。它涵盖项目脚手架、项目配置、构建、桌面及无头测试和插件打包。
主要功能
- 01按目标产品选择项目模板与依赖
- 02配置 .NET 目标框架和平台设置
- 03创建启动配置并构建插件
- 04通过 NETLOAD 或 accoreconsole 测试
- 05打包桌面插件或 Design Automation Bundle
适用场景
- 01创建 AutoCAD 或 Civil 3D 插件项目
- 02在 accoreconsole 中进行无头本地测试
- 03为桌面加载或 Design Automation 准备插件包
MCP 相关
README 未提及 MCP。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ autodesk-platform-services/ skills --skill acad-dotnet安装后在 Claude Code 中输入/acad-dotnet确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/autocad-api.mdcivil3d-api.mdcode-sleuth.mdlearnings.mdplant3d-api.mdtemplates/acad/ClassName.csREADME.mdRootNamespace.csprojtemplates/acad/.template.config/template.jsontemplates/acad/RootNamespace.bundle/PackageContents.xmltemplates/acad/RootNamespace.bundle/Contents/.gitkeeptemplates/civil/.gitignoreLICENSEReadMe.mdtemplates/civil/Civil/CivilClassLib.csprojCmd.cstemplates/civil/Civil/.template.config/template.json详细介绍
脚手架技能 — AutoCAD .NET 插件
从头到尾创建新插件项目的 Agentic 步骤。请按顺序执行这些步骤。 此处所有 csproj 模式均已针对 AutoCAD 2027 / .NET 10 验证。
步骤 0 — 确定目标产品
| 用户说 | 目标 | 模板 | 额外包 |
|---|---|---|---|
| “AutoCAD plugin” / “acad add-in” | AutoCAD 2027 | acad | AutoCAD.NET 26.0.0 |
| “Civil 3D plugin” / “c3d add-in” | Civil 3D 2027 | civil | Civil3D.NET 13.9.628 |
| “Plant 3D plugin” / “plant add-in” | Plant 3D 2027 | (手动) | AutoCAD.NET.Core 26.0.0 + SDK DLL 引用 |
| “Design Automation” / “DA” | 任意(无头) | acad | 仅使用 .Core + .Model(不使用 AcMgd) |
步骤 1 — 搭建脚手架
AutoCAD
dotnet new acad -n <ProjectName> -o <ProjectName>
cd <ProjectName>
Civil 3D
dotnet new civil --rootNamespace=<ProjectName> -o <ProjectName>
cd <ProjectName>
Plant 3D(手动)
创建 <ProjectName>/<ProjectName>.csproj — 参见下方 Plant 3D 部分。
步骤 2 — 修正 csproj(重要)
模板可能会生成过时或不正确的设置。请应用以下所有修正:
目标框架
如果模板生成了 net8.0-windows 或 net6.0-windows,请改为 net10.0-windows。
平台目标 — 优先选择 x64,而不是 RuntimeIdentifier
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
**原因:**AutoCAD 会在直接输出目录中查找程序集。RuntimeIdentifier 会创建一个 win-x64 子文件夹,而 AutoCAD/accoreconsole 默认不会搜索该文件夹。
例外:如果导入了跨平台原生 NuGet 包(例如 Oracle 或 SQLite),则确实需要 <RuntimeIdentifier>win-x64</RuntimeIdentifier> 来获取正确的 Windows 二进制文件。在这种少见情况下,还要在 csproj 中添加 <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>,以防止输出被放入无法访问的子文件夹。
GenerateTargetFrameworkAttribute
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
避免与 AutoCAD 主机自身的 TargetFramework 属性冲突。
参考 csproj 模板 — DA / Civil 3D 无头模式
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Nullable>enable</Nullable>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<PackageReference Include="AutoCAD.NET.Core" Version="26.0.0" ExcludeAssets="runtime" />
<PackageReference Include="AutoCAD.NET.Model" Version="26.0.0" ExcludeAssets="runtime" />
</ItemGroup>
</Project>
参考 csproj 模板 — 仅桌面端(带 UI)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Nullable>enable</Nullable>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<PackageReference Include="AutoCAD.NET" Version="26.0.0" ExcludeAssets="runtime" />
</ItemGroup>
</Project>
Plant 3D csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<Nullable>enable</Nullable>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<PackageReference Include="AutoCAD.NET.Core" Version="26.0.0" ExcludeAssets="runtime" />
<PackageReference Include="AutoCAD.NET.Model" Version="26.0.0" ExcludeAssets="runtime" />
</ItemGroup>
<ItemGroup>
<Reference Include="PnIDMgd">
<HintPath>$(PLANT_SDK)\PnIDMgd.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnPDataLinks">
<HintPath>$(PLANT_SDK)\PnPDataLinks.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnPDataObjects">
<HintPath>$(PLANT_SDK)\PnPDataObjects.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnPProjectManagerMgd">
<HintPath>$(PLANT_SDK)\PnPProjectManagerMgd.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnPCommonMgd">
<HintPath>$(PLANT_SDK)\PnPCommonMgd.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnPCommonDbxMgd">
<HintPath>$(PLANT_SDK)\PnPCommonDbxMgd.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="PnIdProjectPartsMgd">
<HintPath>$(PLANT_SDK)\PnIdProjectPartsMgd.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>
通过 Directory.Build.props 设置 PLANT_SDK:
<Project>
<PropertyGroup>
<PLANT_SDK Condition="'$(PLANT_SDK)'==''">D:\SDKS\Plant2027\inc-x64</PLANT_SDK>
</PropertyGroup>
</Project>
步骤 3 — 入口点样板代码
创建 App.cs(或确认模板已生成该文件):
using Autodesk.AutoCAD.Runtime;
[assembly: ExtensionApplication(typeof(<ProjectName>.App))]
[assembly: CommandClass(typeof(<ProjectName>.Commands))]
namespace <ProjectName>;
public class App : IExtensionApplication
{
public void Initialize() { }
public void Terminate() { }
}
步骤 4 — 添加 launchSettings.json
创建 Properties/launchSettings.json。将 <ACAD_HOME> 替换为 AutoCAD 安装路径。
AutoCAD
{
"profiles": {
"<ProjectName>": { "commandName": "Project" },
"AutoCAD2027": {
"commandName": "Executable",
"executablePath": "<ACAD_HOME>\\acad.exe"
}
}
}
Civil 3D
{
"profiles": {
"<ProjectName>": { "commandName": "Project" },
"C3D2027_Metric": {
"commandName": "Executable",
"executablePath": "<ACAD_HOME>\\acad.exe",
"commandLineArgs": "/ld \"<ACAD_HOME>\\AecBase.dbx\" /p \"<<C3D_Metric>>\" /product C3D /language en-US"
},
"C3D2027_Imperial": {
"commandName": "Executable",
"executablePath": "<ACAD_HOME>\\acad.exe",
"commandLineArgs": "/ld \"<ACAD_HOME>\\AecBase.dbx\" /p \"<<C3D_Imperial>>\" /product C3D /language en-US"
}
}
}
Plant 3D
{
"profiles": {
"<ProjectName>": { "commandName": "Project" },
"Plant3D2027": {
"commandName": "Executable",
"executablePath": "<ACAD_HOME>\\acad.exe",
"commandLineArgs": "/product PLNT3D /language \"en-US\""
}
}
}
步骤 5 — 构建并加载
dotnet build -c Debug
输出:bin\Debug\net10.0-windows\<ProjectName>.dll
**桌面端:**在 AutoCAD 中使用 NETLOAD 加载 DLL(参见步骤 5a)。
**accoreconsole:**使用 .scr 脚本执行 SECURELOAD 0,然后执行 NETLOAD;或者使用 /al(参见步骤 6)。
步骤 5a — 桌面 UI 测试(NETLOAD)
首次加载
- 通过 launchSettings 配置文件或直接启动 AutoCAD(或 Civil 3D / Plant 3D)
- 在命令行中输入:
NETLOAD - 浏览到
bin\Debug\net10.0-windows\<ProjectName>.dll - 运行你的命令(例如,
MYCOMMAND)
处理 SECURELOAD
AutoCAD 默认将 SECURELOAD 设为 1,会阻止来自不受信任路径的 DLL。可选方案:
| 方法 | 使用场景 |
|---|---|
在命令行中执行 SECURELOAD 0 | 快速临时测试 — 每个会话都需重置 |
TRUSTEDPATHS 系统变量 | 将构建输出文件夹添加到受信任列表(设置会保存在注册表中) |
TRUSTEDLOCATIONS 对话框 | TRUSTEDPATHS 的 UI 版本 — 设置 > 文件 > 受信任的位置 |
以编程方式添加受信任路径:
TRUSTEDPATHS
在现有值后追加 ;C:\your\build\output\path。
启动时自动加载(不使用 ApplicationPlugins bundle)
如需反复测试,避免每次启动都输入 NETLOAD。请将 DLL 添加到启动组:
- 执行
APPLOAD命令 - 点击启动组下的“内容...”
- 添加你的 DLL
或者在支持路径中使用 acad.lsp / acaddoc.lsp:
;; acaddoc.lsp — runs on every document open
(command "NETLOAD" "C:\\path\\to\\Plugin.dll")
使用 Visual Studio / VS Code 调试
配置好 launchSettings.json 后(步骤 4):
- 在代码中设置断点
- 开始调试(F5)——AutoCAD 会使用所选配置启动
- 在 AutoCAD 中:使用
NETLOAD加载你的 DLL,然后运行命令 - 断点会在 VS 中命中
附加到进程(AutoCAD 已在运行时):
- 调试 > 附加到进程 > 选择
acad.exe
步骤 6 — 使用 accoreconsole 在本地测试(无头模式)
方法 A:通过脚本使用 NETLOAD
创建一个 .scr 脚本文件:
SECURELOAD
0
NETLOAD
C:\full\path\to\Plugin.dll
MYCOMMAND
启动:
accoreconsole.exe /i "drawing.dwg" /s "test.scr" /ld "AecBase.dbx" /product C3D /language en-US
方法 B:使用 /al 和 .bundle(推荐)
这种方式更接近 DA 的行为。创建一个 bundle 文件夹结构:
TestBundle/
<ProjectName>.bundle/
PackageContents.xml
Contents/
<ProjectName>.dll
<ProjectName>.deps.json
.scr 只需包含命令(无需 SECURELOAD/NETLOAD):
MYCOMMAND
启动:
accoreconsole.exe /i "drawing.dwg" /al "TestBundle" /s "test.scr" /isolate user1 "D:\Tmp" /ld "AecBase.dbx" /product C3D /language en-US
规则:
/al指向.bundle文件夹的父文件夹- 始终使用
/isolate,以防止将注册表写入工作目录 - 完整的标志参考请参阅
autocad-api.md。
步骤 7 — ApplicationPlugins Bundle(桌面自动加载)
对于桌面部署(非 DA),将 .bundle 文件夹放在以下路径之一:
| 路径 | 范围 | 需要管理员权限 |
|---|---|---|
%APPDATA%\Autodesk\ApplicationPlugins\ | 当前用户 | 否 |
C:\Program Files\Autodesk\ApplicationPlugins\ | 所有用户 | 是 |
AutoCAD 会在启动时扫描这些路径,并加载其中含有有效 PackageContents.xml 的 .bundle。
最小化的 .NET 插件 bundle
%APPDATA%\Autodesk\ApplicationPlugins\
<ProjectName>.bundle/
PackageContents.xml
Contents/
<ProjectName>.dll
<ProjectName>.deps.json
注册命令的 PackageContents.xml
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage SchemaVersion="1.0" Version="1.0.0"
ProductCode="{generate-new-guid}"
Name="<ProjectName>"
Description="..."
Author="...">
<CompanyDetails Name="..." Url="..." Email="..." />
<RuntimeRequirements
Platform="AutoCAD"
SeriesMin="R26.0" SeriesMax="R26.0"
OS="Win64" />
<Components Description="plugin">
<RuntimeRequirements
SupportPath="./Contents"
Platform="AutoCAD"
SeriesMin="R26.0" SeriesMax="R26.0"
OS="Win64" />
<ComponentEntry
AppName="<ProjectName>"
AppType=".NET"
Version="1.0.0"
ModuleName="./Contents/<ProjectName>.dll"
AppDescription="..."
LoadOnAutoCADStartup="True"
LoadOnCommandInvocation="False">
<Commands GroupName="<ProjectName>_Commands">
<Command Local="MYCOMMAND" Global="MYCOMMAND" />
</Commands>
</ComponentEntry>
</Components>
</ApplicationPackage>
关键属性:
Platform:AutoCAD(基础版)、Civil3D、Plant3D,或使用竖线分隔的AutoCAD|Civil3DSeriesMin/SeriesMax:R26.0= 2027,R25.1= 2026,R25.0= 2025LoadOnAutoCADStartup="True":启动时立即加载 DLLLoadOnCommandInvocation="True"+LoadOnAutoCADStartup="False":延迟加载(仅在调用命令时加载)SupportPath="./Contents":将 Contents 文件夹添加到 AutoCAD 的支持文件搜索路径<Commands>:注册命令,让 AutoCAD 知道按需加载哪个 bundle
用于在本地部署 bundle 的构建脚本
$BundleName = "<ProjectName>"
$BuildOut = "bin\Debug\net10.0-windows"
$BundleDest = "$env:APPDATA\Autodesk\ApplicationPlugins\$BundleName.bundle"
# Create bundle structure
New-Item "$BundleDest\Contents" -ItemType Directory -Force | Out-Null
Copy-Item "PackageContents.xml" "$BundleDest\" -Force
Copy-Item "$BuildOut\$BundleName.dll" "$BundleDest\Contents\" -Force
Copy-Item "$BuildOut\$BundleName.deps.json" "$BundleDest\Contents\" -Force
Write-Host "Deployed to: $BundleDest"
部署后重启 AutoCAD。bundle 会自动加载。
步骤 8 — DA Bundle 打包
PackageContents.xml
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage SchemaVersion="1.0" Version="1.0.0"
ProductCode="{generate-new-guid}"
Name="<ProjectName>"
Description="..."
Author="...">
<CompanyDetails Name="..." Url="..." Email="..." />
<Components Description="plugin">
<RuntimeRequirements
SeriesMin="R26.0" SeriesMax="R26.0"
Platform="AutoCAD"
OS="Win64" />
<ComponentEntry
AppName="<ProjectName>"
Version="1.0.0"
ModuleName="./Contents/<ProjectName>.dll"
AppDescription="..."
LoadOnAutoCADStartup="True"
LoadOnCommandInvocation="False" />
</Components>
</ApplicationPackage>
SeriesMin/SeriesMax:R26.0 = AutoCAD 2027。必须与 DA 引擎版本一致。
Bundle 文件夹结构
<ProjectName>.bundle/
PackageContents.xml
Contents/
<ProjectName>.dll
<ProjectName>.deps.json
正确压缩(至关重要)
# CORRECT — bundle folder is zip root
Compress-Archive -Path "$ProjectName.bundle" -DestinationPath "$ProjectName.zip"
# WRONG — puts PackageContents.xml at zip root; bundle silently not loaded
Compress-Archive -Path "$ProjectName.bundle\*" -DestinationPath "$ProjectName.zip"
DA Activity commandLine
$(engine.path)\accoreconsole.exe /i "$(args[inputFile].path)" /al "$(appbundles[<BundleName>].path)" /s "$(settings[script].path)"
/al从父文件夹加载 .bundle(本地使用方式见下文)/s传入包含命令调用的脚本
在本地通过 accoreconsole 使用 /al(未公开记录)
/al 在桌面版 accoreconsole 中也能使用——只是没有写入官方文档。参数是包含 .bundle 目录的父文件夹:
TestFolder/
MyPlugin.bundle/
PackageContents.xml
Contents/
MyPlugin.dll
启动:
accoreconsole.exe /i "drawing.dwg" /al "D:\TestFolder" /s "test.scr" /isolate user1 "D:\Tmp"
规则:
/al指向.bundle文件夹的父文件夹,而不是 bundle 本身- 始终使用
/isolate——否则/al会将注册表项写入父文件夹,污染工作目录 /isolate user1 <tempDir>会将这些注册表写入重定向到临时目录- 使用
/al时,.scr脚本不需要SECURELOAD 0或NETLOAD——bundle 会自动加载
DA 引擎 ID(使用 + 而非 .)
| 产品 | 引擎 ID |
|---|---|
| AutoCAD 2027 | Autodesk.AutoCAD+26_0 |
| AutoCAD 2026 | Autodesk.AutoCAD+25_1 |
| AutoCAD 2025 | Autodesk.AutoCAD+25_0 |
已验证的构建输出路径
使用正确的 csproj 设置执行 dotnet build -c Debug 后:
bin\Debug\net10.0-windows\<ProjectName>.dll ← load this
bin\Debug\net10.0-windows\<ProjectName>.deps.json
bin\Debug\net10.0-windows\<ProjectName>.pdb
如果看到 bin\Debug\net10.0-windows\win-x64\ 子文件夹,说明你的 csproj 中设置了 RuntimeIdentifier,但没有正确覆盖。请移除它并使用 PlatformTarget,或设置 <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>。