将 CycleGUI 开发技能(含 Duplicated id 防碰撞规范)纳入 .cursor/skills,并调整 gitignore 仅放行 skills 目录可提交。 Co-authored-by: Cursor <cursoragent@cursor.com>
4.6 KiB
项目搭建、引用策略和启动流程
三类项目
- CycleGUI 同解决方案内示例:例如
LearnCycleGUI,可ProjectReference到CycleGUI\CycleGUI.csproj。 - 宿主/调度程序:例如
SimpleLite,引用真实CycleGUI.dll,用Costura.Fody把托管程序集包进宿主 Assembly。 - 插件或二次开发项目:默认引用
RefCycleGUI.dll,不要引用真实CycleGUI.dll。真实实现由宿主提供,以保护和隔离 CycleGUI 代码资产。
插件/二开项目模板
<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。
宿主程序模板
<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:
<Weavers>
<Costura />
</Weavers>
native 依赖如 libVRender.dll 按宿主自己的资源、输出目录或加载策略处理,不要把插件二开项目设计成显式部署真实 CycleGUI.dll。
同解决方案示例模板
<ItemGroup>
<ProjectReference Include="..\..\CycleGUI\CycleGUI.csproj" />
</ItemGroup>
只在跟 CycleGUI 源码一起开发和验证的示例中使用该模式。
常用 using
using CycleGUI;
using CycleGUI.API;
using CycleGUI.Terminals;
using System.Drawing;
using System.Numerics;
本地启动
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 启动
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 同时用于三处。
- exe 可执行程序图标:csproj 里
<ApplicationIcon>,编译期写入 PE 资源,资源管理器/任务栏看到的就是它。
<PropertyGroup>
<ApplicationIcon>res\app_icon.ico</ApplicationIcon>
</PropertyGroup>
-
LocalTerminal 托盘 / 窗口图标:
LocalTerminal.SetIcon(byte[] icoBytes, string name),传.ico文件字节,须在LocalTerminal.Start()之前调用。 -
WebTerminal 浏览器 favicon:
WebTerminal.Use(int port, byte[] ico = null),把同一份.ico字节作为ico:传入。
icoBytes 的两种来源:
// 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)适合图标可替换的场景。
完整三处一起设置:
<!-- .csproj -->
<PropertyGroup>
<ApplicationIcon>res\app_icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="res\app_icon.ico" />
</ItemGroup>
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。