Skip to content

Commit 87f5b91

Browse files
authored
Merge pull request #1 from Tritium0041/main
@Tritium0041: 增加内置大模型调用支持
1 parent cbcd460 commit 87f5b91

File tree

14 files changed

+1258
-103
lines changed

14 files changed

+1258
-103
lines changed

.github/workflows/build.yml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Build MSIX Installer
2+
3+
# 触发条件:
4+
# - 推送到 main / copilot/** 分支时自动构建
5+
# - 向 main 分支发起 PR 时自动构建
6+
# - 支持在 Actions 页面手动触发
7+
on:
8+
push:
9+
branches:
10+
- main
11+
- 'copilot/**'
12+
pull_request:
13+
branches:
14+
- main
15+
workflow_dispatch:
16+
17+
env:
18+
CONFIGURATION: Release
19+
PLATFORM: x64
20+
# MSIX 输出目录(相对于仓库根目录)
21+
APPX_DIR: AppPackages
22+
23+
jobs:
24+
build:
25+
name: Build & Package (Windows x64)
26+
runs-on: windows-latest
27+
28+
steps:
29+
# ── 1. 检出代码 ──────────────────────────────────────────────────────────
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
33+
# ── 2. 配置 .NET 8 SDK ───────────────────────────────────────────────────
34+
- name: Setup .NET SDK 8.0
35+
uses: actions/setup-dotnet@v4
36+
with:
37+
dotnet-version: '8.0.x'
38+
39+
# ── 3. 配置 MSBuild (Visual Studio 2022) ─────────────────────────────────
40+
- name: Setup MSBuild
41+
uses: microsoft/setup-msbuild@v2
42+
43+
# ── 4. 还原 NuGet 包 ──────────────────────────────────────────────────────
44+
- name: Restore NuGet packages
45+
run: dotnet restore RunOnce/RunOnce.csproj -p:Platform=${{ env.PLATFORM }}
46+
47+
# ── 5. 编译 C++ ShellExt.dll ──────────────────────────────────────────────
48+
- name: Build ShellExt (C++ DLL, Release|x64)
49+
run: >
50+
msbuild ShellExt/ShellExt.vcxproj
51+
/p:Configuration=${{ env.CONFIGURATION }}
52+
/p:Platform=${{ env.PLATFORM }}
53+
/m /nologo /verbosity:minimal
54+
55+
# ── 6. 生成自签名证书(主题必须与 Package.appxmanifest 中 Publisher 完全一致)─
56+
- name: Generate self-signed signing certificate
57+
shell: pwsh
58+
run: |
59+
$publisher = "CN=28B58DEE-3276-4667-848D-FC06656EFB1D"
60+
$cert = New-SelfSignedCertificate `
61+
-Type Custom `
62+
-Subject $publisher `
63+
-KeyUsage DigitalSignature `
64+
-FriendlyName "RunOnce Self-Signed" `
65+
-CertStoreLocation "Cert:\CurrentUser\My" `
66+
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")
67+
68+
# 导出 PFX(供 MSBuild 签名使用)
69+
$pfxPassword = ConvertTo-SecureString -String "RunOnce-CI" -Force -AsPlainText
70+
Export-PfxCertificate `
71+
-Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
72+
-FilePath RunOnce/RunOnce_TemporaryKey.pfx `
73+
-Password $pfxPassword
74+
75+
# 导出 .cer(供用户在安装前信任证书使用)
76+
Export-Certificate `
77+
-Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
78+
-FilePath RunOnce_SideloadCert.cer `
79+
-Type CERT
80+
81+
Write-Host "Certificate thumbprint: $($cert.Thumbprint)"
82+
83+
# ── 7. 编译并打包 MSIX ────────────────────────────────────────────────────
84+
- name: Build and Package MSIX
85+
shell: pwsh
86+
run: |
87+
$pfxPath = Join-Path $env:GITHUB_WORKSPACE "RunOnce/RunOnce_TemporaryKey.pfx"
88+
msbuild RunOnce/RunOnce.csproj `
89+
/p:Configuration=${{ env.CONFIGURATION }} `
90+
/p:Platform=${{ env.PLATFORM }} `
91+
/p:GenerateAppxPackageOnBuild=True `
92+
/p:AppxPackageSigningEnabled=True `
93+
/p:GenerateTemporaryStoreCertificate=False `
94+
/p:PackageCertificateKeyFile="$pfxPath" `
95+
/p:PackageCertificatePassword="RunOnce-CI" `
96+
/p:AppxBundle=Never `
97+
/p:UapAppxPackageBuildMode=SideloadOnly `
98+
/p:AppxPackageDir="$env:GITHUB_WORKSPACE\${{ env.APPX_DIR }}\" `
99+
/p:GenerateTestArtifacts=True `
100+
/m /nologo /verbosity:minimal
101+
102+
# ── 8. 校验并列出构建产物(防止上传缺少 .msix 的空包)──────────────────────
103+
- name: Validate and list package artifacts
104+
shell: pwsh
105+
run: |
106+
$appxDir = "${{ env.APPX_DIR }}"
107+
Write-Host "=== AppPackages ==="
108+
Get-ChildItem -Recurse $appxDir -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
109+
$msixFiles = Get-ChildItem -Recurse $appxDir -Filter *.msix -File -ErrorAction SilentlyContinue
110+
if (-not $msixFiles) {
111+
Write-Error "No .msix file found under $appxDir. Packaging did not produce an installer."
112+
exit 1
113+
}
114+
115+
# ── 9. 写入安装说明 ───────────────────────────────────────────────────────
116+
- name: Write install instructions
117+
shell: pwsh
118+
run: |
119+
$content = @"
120+
# RunOnce 安装说明
121+
122+
## 安装前提
123+
RunOnce 以旁加载 (Sideload) 方式分发,安装前需先信任签名证书。
124+
125+
## 安装步骤
126+
127+
### 方法一:使用安装脚本(推荐)
128+
1. 以**管理员**身份打开 PowerShell
129+
2. 进入下载并解压后的文件夹
130+
3. 运行:
131+
\`\`\`powershell
132+
Set-ExecutionPolicy Bypass -Scope Process
133+
.\Add-AppDevPackage.ps1
134+
\`\`\`
135+
脚本会自动安装证书并完成应用安装。
136+
137+
### 方法二:手动安装
138+
1. 双击 **RunOnce_SideloadCert.cer**
139+
2. 选择「安装证书」→「本地计算机」→「受信任的根证书颁发机构」→ 完成
140+
3. 双击 **.msix** 文件,按提示完成安装
141+
142+
## 系统要求
143+
- Windows 11(版本 22000 或更高)
144+
- 已安装 [Windows App Runtime](https://aka.ms/windowsappsdk) 1.8+
145+
"@
146+
$content | Out-File -FilePath INSTALL.md -Encoding utf8
147+
148+
# ── 10. 上传构建产物 ──────────────────────────────────────────────────────
149+
- name: Upload MSIX artifact
150+
uses: actions/upload-artifact@v4
151+
with:
152+
name: RunOnce-MSIX-${{ env.CONFIGURATION }}-${{ env.PLATFORM }}
153+
path: |
154+
${{ env.APPX_DIR }}/**/*.msix
155+
${{ env.APPX_DIR }}/**/*.ps1
156+
RunOnce_SideloadCert.cer
157+
INSTALL.md
158+
if-no-files-found: error
159+
retention-days: 30

RunOnce/App.xaml.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#nullable enable
1111

12+
using System;
1213
using Microsoft.UI.Xaml;
1314
using RunOnce.Static;
1415

@@ -41,6 +42,12 @@ public partial class App : Application
4142
/// <value>通常用于从右键菜单传入工作目录路径。启动时无参数则为空字符串。</value>
4243
public string LaunchArguments { get; private set; } = string.Empty;
4344

45+
/// <summary>
46+
/// 获取应用程序是否以 AI 生成模式启动。
47+
/// </summary>
48+
/// <value>当启动参数中包含 <c>--ai</c> 标志时为 true。</value>
49+
public bool IsAiMode { get; private set; }
50+
4451
/// <summary>
4552
/// 初始化应用程序实例。
4653
/// </summary>
@@ -58,7 +65,26 @@ public App()
5865
/// </remarks>
5966
protected override void OnLaunched(LaunchActivatedEventArgs args)
6067
{
61-
LaunchArguments = args.Arguments ?? string.Empty;
68+
string rawArgs = args.Arguments ?? string.Empty;
69+
70+
// 检测并剥离 --ai 标志
71+
const string aiFlag = " --ai";
72+
if (rawArgs.EndsWith(aiFlag, StringComparison.OrdinalIgnoreCase))
73+
{
74+
IsAiMode = true;
75+
LaunchArguments = rawArgs[..^aiFlag.Length].Trim();
76+
}
77+
else if (rawArgs.Equals("--ai", StringComparison.OrdinalIgnoreCase))
78+
{
79+
IsAiMode = true;
80+
LaunchArguments = string.Empty;
81+
}
82+
else
83+
{
84+
IsAiMode = false;
85+
LaunchArguments = rawArgs;
86+
}
87+
6288
_mainWindow = new MainWindow();
6389
ApplyTheme(Config.Theme);
6490
_mainWindow.Activate();
@@ -97,4 +123,4 @@ public void UpdateTheme(ThemeStyle theme)
97123
Config.Theme = theme;
98124
ApplyTheme(theme);
99125
}
100-
}
126+
}

RunOnce/MainWindow.xaml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<ColumnDefinition Width="Auto"/>
2424
<ColumnDefinition Width="Auto"/>
2525
<ColumnDefinition Width="Auto"/>
26+
<ColumnDefinition Width="Auto"/>
2627
</Grid.ColumnDefinitions>
2728

2829
<!-- 返回按钮 -->
@@ -69,10 +70,22 @@
6970
</Grid>
7071
</Button>
7172

73+
<!-- AI 生成按钮 -->
74+
<Button
75+
x:Name="AiButton"
76+
Grid.Column="3"
77+
Style="{ThemeResource SubtleButtonStyle}"
78+
Width="48"
79+
Height="48"
80+
Visibility="Visible"
81+
Click="AiButton_Click">
82+
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}" Glyph="&#xE82F;" FontSize="14"/>
83+
</Button>
84+
7285
<!-- 运行按钮 -->
7386
<Button
7487
x:Name="RunButton"
75-
Grid.Column="3"
88+
Grid.Column="4"
7689
Style="{ThemeResource SubtleButtonStyle}"
7790
Width="48"
7891
Height="48"
@@ -84,7 +97,7 @@
8497
<!-- 设置按钮 -->
8598
<Button
8699
x:Name="SettingsButton"
87-
Grid.Column="4"
100+
Grid.Column="5"
88101
Style="{ThemeResource SubtleButtonStyle}"
89102
Width="48"
90103
Height="48"

RunOnce/MainWindow.xaml.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ private void UpdateLocalizedTexts()
201201
Title = appName;
202202
AppTitleTextBlock.Text = appName;
203203
ToolTipService.SetToolTip(ArgsButton, $"{Text.Localize("命令行参数")} (Ctrl+E)");
204+
ToolTipService.SetToolTip(AiButton, $"{Text.Localize("AI 生成代码")} (Ctrl+G)");
204205
ToolTipService.SetToolTip(RunButton, $"{Text.Localize("运行")} (Ctrl+Enter)");
205206
}
206207

@@ -263,6 +264,7 @@ private void UpdateTitleBarButtons()
263264
{
264265
BackButton.Visibility = _isInSettingsPage ? Visibility.Visible : Visibility.Collapsed;
265266
ArgsButton.Visibility = _isInSettingsPage ? Visibility.Collapsed : Visibility.Visible;
267+
AiButton.Visibility = _isInSettingsPage ? Visibility.Collapsed : Visibility.Visible;
266268
RunButton.Visibility = _isInSettingsPage ? Visibility.Collapsed : Visibility.Visible;
267269
SettingsButton.Visibility = _isInSettingsPage ? Visibility.Collapsed : Visibility.Visible;
268270
}
@@ -290,6 +292,19 @@ private async void ArgsButton_Click(object sender, RoutedEventArgs e)
290292
}
291293
}
292294

295+
/// <summary>
296+
/// AI 生成按钮点击事件处理程序。
297+
/// </summary>
298+
/// <param name="sender">事件源对象。</param>
299+
/// <param name="e">路由事件参数。</param>
300+
private async void AiButton_Click(object sender, RoutedEventArgs e)
301+
{
302+
if (ContentFrame.Content is Editor editorPage)
303+
{
304+
await editorPage.HandleAiGenerateAsync();
305+
}
306+
}
307+
293308
/// <summary>
294309
/// 运行按钮点击事件处理程序。
295310
/// </summary>

RunOnce/Package.appxmanifest

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
Id="D4E5F601-A2B3-4C5D-8E9F-0A1B2C3D4E5F"
5656
Path="ShellExt.dll"
5757
ThreadingModel="STA" />
58+
<com:Class
59+
Id="E1C5F602-A3B4-5C6D-9E0F-1A2B3C4D5E6F"
60+
Path="ShellExt.dll"
61+
ThreadingModel="STA" />
5862
</com:SurrogateServer>
5963
</com:ComServer>
6064
</com:Extension>
@@ -65,6 +69,9 @@
6569
<desktop5:Verb
6670
Id="RunOnceHere"
6771
Clsid="D4E5F601-A2B3-4C5D-8E9F-0A1B2C3D4E5F" />
72+
<desktop5:Verb
73+
Id="RunOnceAiHere"
74+
Clsid="E1C5F602-A3B4-5C6D-9E0F-1A2B3C4D5E6F" />
6875
</desktop5:ItemType>
6976
</desktop4:FileExplorerContextMenus>
7077
</desktop4:Extension>

0 commit comments

Comments
 (0)