# process.dotnet 库模块帮助文档

<details>  <summary>用法</summary>  <p>

### 默认调用

```aardio
import process.dotnet;

//不要与标准库 dotNet 混淆，aardio 标识符区分大小写
var dotnet,err = process.dotnet();
if(!dotnet) error(err);

var pipe,err = dotnet("--info"); 
if(!pipe) error(err);

var output,stderr,exitCode = pipe.readAll();
print(output,stderr,exitCode);
```

### 独立选择 SDK

```aardio
import process.dotnet;
var dotnet,err = process.dotnet("8.0");
if(!dotnet) error(err);

print("实际 SDK：",dotnet.version);
var pipe,err = dotnet("--version");

if(!pipe) error(err);
print(pipe.readAll());
```

`process.dotnet("8.0")` 选择 SDK 8，不会因同时安装 SDK 10 而偷偷使用 SDK 10。
要用 SDK 10 编译 net8.0 项目，则选择 SDK 10，并在 csproj 中设置 `TargetFramework=net8.0`。
`dotnet(...)`（等同于 `dotnet.run(...)`）直接运行所选 SDK 的 CLI 程序；普通应用 DLL 可用 `process.popen(dotnet.path,"应用.dll")` 执行。
构造 SDK 对象不连接 AutoCAD，也不把现代程序集载入 aardio 的 .NET Framework CLR。

工作目录通常只需设置一次 `dotnet.workDir`，各实例互不影响。构造时依次采用 `options.workDir`、`process.dotnet.workDir`、应用程序基准目录；单次调用第 2 个参数中的 `workDir` 可临时覆盖，但不修改实例的默认值。

### 编译 C# 为 DLL

```aardio 
import process.dotnet;

print("正在准备 .NET SDK"); //交互环境应提示，避免长时间安装阻塞，Agent 环境可省略
var dotnet,err = process.dotnet("8.0");
if(!dotnet) error(err);

print("正在编译"); //无头自动化环境可省略
dotnet.workDir = "/build-dotnet-demo";
string.saveFiles(dotnet.workDir,{
	"Hello.csproj" = /***
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup>
</Project>
***/;
	"Hello.cs" = /***
public static class Hello { 
	public static int Add(int a,int b) => a+b; 
}
***/;
});

/*
命令行参数支持多种写法，与 process/process.popen 相同：
STARTUPINFO 只放在第 2 个用户参数，不从多个参数的末尾提取表。
dotnet("build Hello.csproj -c Release",{workDir="/build-dotnet-demo"}); //临时覆盖目录
dotnet("build","Hello.csproj","-c","Release"); //多个字符串由 aardio 负责命令行转义与拼接
dotnet(["build","Hello.csproj","-c","Release"]); //数组由 aardio 负责命令行转义与拼接
dotnet(["build","Hello.csproj","-c","Release"],{workDir="/build-dotnet-demo"});
*/
var pipe,err = dotnet("build Hello.csproj -c Release");
if(!pipe) error(err);

var output,stderr,exitCode = pipe.readAll();
if(exitCode!=0) error(output);

var dll = io.joinpath(dotnet.workDir,"bin/Release/net8.0/Hello.dll");
print(dll);
```

安装使用微软官方脚本，默认目录为 `%LOCALAPPDATA%\Microsoft\dotnet`，无需管理员权限，不改系统 SDK/PATH。
首次安装、还原参考包需要联网；复用已安装 SDK 不联网。显式 `latest` 首次查询在线发布索引。
构建的完整错误可能在 stdout；以 `readAll()` 的第 3 个返回值 `exitCode==0` 判断构建进程成功，不能仅检查 stderr 或旧 DLL 是否存在。

</p></details>

## process 成员列表 <a id="process" href="#process">&#x23;</a>

### process.dotnet() <a id="process.dotnet" href="#process.dotnet">&#x23;</a>
[返回对象:processDotnetSdkObject](#processDotnetSdkObject)

### process.dotnet(版本,选项) <a id="process.dotnet" href="#process.dotnet">&#x23;</a>
版本省略：复用最高本地稳定 SDK（8+），没有则安装最新稳定版。  
8 或 "8.0"：同主次版本最高本地稳定 SDK，缺少则安装该系列最新稳定版。  
"10.0.401"：精确 SDK 版本。"latest"：查询微软当前最新稳定 SDK。  
发现结果在线程内缓存；setPath 可清除缓存。  
选项可指定 workDir、path（限定发现路径）、installDir（私有安装目录）、install=false（不安装）、echo=true（回显安装输出）。

## process.dotnet 成员列表 <a id="process.dotnet" href="#process.dotnet">&#x23;</a>

创建 .NET 8+ SDK 调用对象。仅发现与自动安装稳定 SDK；运行时不等于 SDK。

发现/安装并返回独立的 SDK 调用对象。不修改全局版本、PATH 或 global.json。  
成功返回对象，失败返回 null、错误信息、诊断表。

### process.dotnet.getPath() <a id="process.dotnet.getPath" href="#process.dotnet.getPath">&#x23;</a>
获取具有现代稳定 SDK 的 dotnet.exe 路径，无可用 SDK 时自动安装最新稳定版。  
可选参数 @1 为 true 时回显安装输出。失败返回 null、错误信息、诊断表。

### process.dotnet.setPath() <a id="process.dotnet.setPath" href="#process.dotnet.setPath">&#x23;</a>
指定优先使用的 dotnet.exe，清除发现缓存；null 恢复自动发现。  
此路径没有合适 SDK 时仍可安装到用户私有目录，不改写指定路径。

### process.dotnet.workDir <a id="process.dotnet.workDir" href="#process.dotnet.workDir">&#x23;</a>
可选指定默认命令工作目录，不指定则默认为应用程序基准目录。  
单次 startupInfo.workDir 优先，不修改系统当前目录。

## processDotnetSdkObject 成员列表 <a id="processDotnetSdkObject" href="#processDotnetSdkObject">&#x23;</a>

### processDotnetSdkObject.path <a id="processDotnetSdkObject.path" href="#processDotnetSdkObject.path">&#x23;</a>
dotnet.exe 的完整路径。

### processDotnetSdkObject.run <a id="processDotnetSdkObject.run" href="#processDotnetSdkObject.run">&#x23;</a>
此方法名为对象的默认方法，可省略方法名 `.run`。  
通过 dotnet exec 调用所选 SDK 的 dotnet.dll，绑定 SDK 版本。  
不受其他目录 global.json 的 CLI 版本选择影响，不修改该文件。  
仅用于 SDK 命令；运行普通应用 DLL 可使用 process.popen 。  

返回 UTF-8 进程管道（process.popen），readAll 方法返回完整输出、stderr、退出码。  
环境表默认关闭欢迎信息、遥测与开发证书生成，并指定 UTF-8；单次环境表可覆盖，原始环境块原样传递。

### processDotnetSdkObject.run() <a id="processDotnetSdkObject.run" href="#processDotnetSdkObject.run">&#x23;</a>
[返回对象:processPopenObject](https://www.aardio.com/zh-cn/docs/library-reference/process/popen.html#processPopenObject)

### processDotnetSdkObject.run(命令行参数,startupInfo) <a id="processDotnetSdkObject.run" href="#processDotnetSdkObject.run">&#x23;</a>
所有参数用法与 process.popen 相同。  
优先传单个字符串，用空格分隔命令行参数。  
数组参数调用 process.joinArguments 自动转义与拼接。  
仅第 2 个用户参数可指定 STARTUPINFO；多字符串形式不从末尾提取表。  
startupInfo 同 process.popen；单次工作目录和环境变量优先。

### processDotnetSdkObject.run(命令行参数,更多命令行参数,...) <a id="processDotnetSdkObject.run" href="#processDotnetSdkObject.run">&#x23;</a>
命令行参数可以是一个数组、一个或多个字符串参数。  

数组或多个命令行参数调用 process.joinArguments 合并。

### processDotnetSdkObject.sdkDir <a id="processDotnetSdkObject.sdkDir" href="#processDotnetSdkObject.sdkDir">&#x23;</a>
实际 SDK 目录。

### processDotnetSdkObject.version <a id="processDotnetSdkObject.version" href="#processDotnetSdkObject.version">&#x23;</a>
实际选择的完整 SDK 版本；不等于项目的 TargetFramework。

### processDotnetSdkObject.workDir <a id="processDotnetSdkObject.workDir" href="#processDotnetSdkObject.workDir">&#x23;</a>
自定义当前实例的命令工作目录，各实例独立。  
构造时依次采用 options.workDir、process.dotnet.workDir、应用程序基准目录。  
单次调用第 2 个参数中的 workDir 可临时覆盖，不修改实例。
