152 lines
4.6 KiB
Markdown
152 lines
4.6 KiB
Markdown
# 项目搭建、引用策略和启动流程
|
||||
|
|
|
|||
|
|
## 三类项目
|
|||
|
|
|
|||
|
|
1. **CycleGUI 同解决方案内示例**:例如 `LearnCycleGUI`,可 `ProjectReference` 到 `CycleGUI\CycleGUI.csproj`。
|
|||
|
|
2. **宿主/调度程序**:例如 `SimpleLite`,引用真实 `CycleGUI.dll`,用 `Costura.Fody` 把托管程序集包进宿主 Assembly。
|
|||
|
|
3. **插件或二次开发项目**:默认引用 `RefCycleGUI.dll`,不要引用真实 `CycleGUI.dll`。真实实现由宿主提供,以保护和隔离 CycleGUI 代码资产。
|
|||
|
|
|
|||
|
|
## 插件/二开项目模板
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<Project Sdk="Microsoft.NET.Sdk">
|
|||
|
|
<PropertyGroup>
|
|||
|
|
<TargetFramework>net8.0</TargetFramework>
|
|||
|
|
<ImplicitUsings>enable</ImplicitUsings>
|
|||
|
|
<Nullable>enable</Nullable>
|
|||
|
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|||
|
|
</PropertyGroup>
|
|||
|
|
|
|||
|
|
<ItemGroup>
|
|||
|
|
<Reference Include="CycleGUI">
|
|||
|
|
<HintPath>$(CGUILibDir)RefCycleGUI.dll</HintPath>
|
|||
|
|
<Private>false</Private>
|
|||
|
|
</Reference>
|
|||
|
|
</ItemGroup>
|
|||
|
|
</Project>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`Private=false` 用于避免把 Ref 程序集复制成插件自己的运行时依赖。宿主进程负责提供真实 CycleGUI。
|
|||
|
|
|
|||
|
|
## 宿主程序模板
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<ItemGroup>
|
|||
|
|
<PackageReference Include="Costura.Fody" Version="5.7.0">
|
|||
|
|
<PrivateAssets>all</PrivateAssets>
|
|||
|
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|||
|
|
</PackageReference>
|
|||
|
|
<Reference Include="CycleGUI">
|
|||
|
|
<HintPath>$(CGUILibDir)CycleGUI.dll</HintPath>
|
|||
|
|
</Reference>
|
|||
|
|
</ItemGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`FodyWeavers.xml`:
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<Weavers>
|
|||
|
|
<Costura />
|
|||
|
|
</Weavers>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
native 依赖如 `libVRender.dll` 按宿主自己的资源、输出目录或加载策略处理,不要把插件二开项目设计成显式部署真实 `CycleGUI.dll`。
|
|||
|
|
|
|||
|
|
## 同解决方案示例模板
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<ItemGroup>
|
|||
|
|
<ProjectReference Include="..\..\CycleGUI\CycleGUI.csproj" />
|
|||
|
|
</ItemGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
只在跟 CycleGUI 源码一起开发和验证的示例中使用该模式。
|
|||
|
|
|
|||
|
|
## 常用 using
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
using CycleGUI;
|
|||
|
|
using CycleGUI.API;
|
|||
|
|
using CycleGUI.Terminals;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.Numerics;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 本地启动
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Terminal.RegisterRemotePanel(CreateMainPanel);
|
|||
|
|
|
|||
|
|
LocalTerminal.SetTitle("MyApp");
|
|||
|
|
LocalTerminal.SetIcon(icoBytes, "MyApp");
|
|||
|
|
LocalTerminal.AddMenuItem("Exit", LocalTerminal.Terminate);
|
|||
|
|
LocalTerminal.Start();
|
|||
|
|
GUI.PromptPanel(CreateMainPanel(GUI.defaultTerminal));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`Terminal.RegisterRemotePanel` 让 TCP/Web 终端连接后也能拿到欢迎面板。`GUI.PromptPanel` 显示本地默认终端上的主面板。
|
|||
|
|
|
|||
|
|
## Web 启动
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Task.Run(() => WebTerminal.Use(port: 8081, ico: icoBytes));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
可配合 `LeastServer` 发布静态文件和简单 HTTP API。Web 细节见 `terminals-and-web.md`。
|
|||
|
|
|
|||
|
|
## 图标设置(exe / 托盘 / Web favicon)
|
|||
|
|
|
|||
|
|
三处图标**统一用 `.ico` 格式**(Windows 图标;建议内含 16/32/48 多尺寸,需要高清可再加 256)。常见做法是一个 `.ico` 同时用于三处。
|
|||
|
|
|
|||
|
|
1. **exe 可执行程序图标**:csproj 里 `<ApplicationIcon>`,编译期写入 PE 资源,资源管理器/任务栏看到的就是它。
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<PropertyGroup>
|
|||
|
|
<ApplicationIcon>res\app_icon.ico</ApplicationIcon>
|
|||
|
|
</PropertyGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **LocalTerminal 托盘 / 窗口图标**:`LocalTerminal.SetIcon(byte[] icoBytes, string name)`,传 `.ico` 文件字节,须在 `LocalTerminal.Start()` 之前调用。
|
|||
|
|
|
|||
|
|
3. **WebTerminal 浏览器 favicon**:`WebTerminal.Use(int port, byte[] ico = null)`,把同一份 `.ico` 字节作为 `ico:` 传入。
|
|||
|
|
|
|||
|
|
`icoBytes` 的两种来源:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// A) 把 .ico 作为嵌入资源(csproj: <EmbeddedResource Include="app_icon.ico" />),运行时读出
|
|||
|
|
static byte[] LoadIcon()
|
|||
|
|
{
|
|||
|
|
var asm = Assembly.GetExecutingAssembly();
|
|||
|
|
using var s = asm.GetManifestResourceStream(
|
|||
|
|
asm.GetManifestResourceNames().First(p => p.Contains(".ico")));
|
|||
|
|
return new BinaryReader(s).ReadBytes((int)s.Length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// B) 直接从磁盘文件读
|
|||
|
|
byte[] icoBytes = File.ReadAllBytes("res/app_icon.ico");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
嵌入式(A)适合单文件分发,图标随程序集走、不依赖外部文件;磁盘式(B)适合图标可替换的场景。
|
|||
|
|
|
|||
|
|
完整三处一起设置:
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<!-- .csproj -->
|
|||
|
|
<PropertyGroup>
|
|||
|
|
<ApplicationIcon>res\app_icon.ico</ApplicationIcon>
|
|||
|
|
</PropertyGroup>
|
|||
|
|
<ItemGroup>
|
|||
|
|
<EmbeddedResource Include="res\app_icon.ico" />
|
|||
|
|
</ItemGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
var icoBytes = LoadIcon();
|
|||
|
|
LocalTerminal.SetTitle("MyApp");
|
|||
|
|
LocalTerminal.SetIcon(icoBytes, "MyApp"); // 托盘 + 窗口
|
|||
|
|
LocalTerminal.Start();
|
|||
|
|
WebTerminal.Use(port: 8081, ico: icoBytes); // Web favicon
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> `SetIcon` / `WebTerminal.Use` 只接受 `.ico` 字节,不要传 PNG/JPG 字节。要从 PNG 生成,请先离线转成多尺寸 `.ico`。
|