diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..04deec3e
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,234 @@
+name: Build and Release
+
+on:
+ push:
+ branches: [ main, beta ]
+ pull_request:
+ branches: [ main, beta ]
+ release:
+ types: [ published ]
+
+env:
+ DOTNET_VERSION: '4.7.2'
+ PROJECT_PATH: 'Ink Canvas'
+ INNO_SETUP_VERSION: '6.2.2'
+
+jobs:
+ build:
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ include:
+ - platform: 'x86'
+ runtime: 'win-x86'
+ configuration: 'Release'
+ arch_suffix: 'x86'
+ - platform: 'x64'
+ runtime: 'win-x64'
+ configuration: 'Release'
+ arch_suffix: 'x64'
+ - platform: 'ARM64'
+ runtime: 'win-arm64'
+ configuration: 'Release'
+ arch_suffix: 'arm64'
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup .NET Framework
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '4.7.2'
+
+ - name: Get version from project
+ id: get_version
+ run: |
+ $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value })
+ echo "version=$version" >> $env:GITHUB_OUTPUT
+ echo "Version: $version"
+
+ - name: Restore NuGet packages
+ run: nuget restore "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj"
+
+ - name: Build solution
+ run: msbuild "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:OutputPath=./publish/${{ matrix.platform }}/ /p:PublishUrl=./publish/${{ matrix.platform }}/
+
+ - name: Copy additional files
+ run: |
+ # 复制配置文件和其他必要文件
+ if (Test-Path "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config") {
+ Copy-Item "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config" -Destination "./publish/${{ matrix.platform }}/"
+ }
+ # 复制Resources文件夹
+ if (Test-Path "${{ env.PROJECT_PATH }}/Resources") {
+ Copy-Item "${{ env.PROJECT_PATH }}/Resources" -Destination "./publish/${{ matrix.platform }}/" -Recurse
+ }
+ # 复制其他必要文件
+ Copy-Item "${{ env.PROJECT_PATH }}/*.dll" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue
+ Copy-Item "${{ env.PROJECT_PATH }}/*.json" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue
+
+ - name: Install Inno Setup
+ if: matrix.platform != 'ARM64'
+ run: |
+ $url = "https://files.jrsoftware.org/is/6/innosetup-${{ env.INNO_SETUP_VERSION }}.exe"
+ $output = "innosetup.exe"
+ Invoke-WebRequest -Uri $url -OutFile $output
+ Start-Process -FilePath $output -ArgumentList "/SILENT" -Wait
+ echo "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" >> $env:GITHUB_PATH
+
+ - name: Create Inno Setup script for current architecture
+ if: matrix.platform != 'ARM64'
+ run: |
+ $scriptContent = @"
+; 自动生成的 Inno Setup 脚本
+#define MyAppName "InkCanvasForClass CE"
+#define MyAppVersion "${{ steps.get_version.outputs.version }}"
+#define MyAppPublisher "CJK_mkp"
+#define MyAppURL "https://inkcanvasforclass.github.io"
+#define MyAppExeName "InkCanvasForClass.exe"
+#define MyAppAssocName MyAppName + ""
+#define MyAppAssocExt ".exe"
+#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt
+
+[Setup]
+AppId={{CA801226-FD02-4C78-BCF8-753B38E70CB3}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={autopf}\{#MyAppName}
+UninstallDisplayIcon={app}\{#MyAppExeName}
+ChangesAssociations=yes
+DefaultGroupName={#MyAppName}
+AllowNoIcons=yes
+PrivilegesRequiredOverridesAllowed=dialog
+OutputDir=./installers
+OutputBaseFilename=InkCanvasForClass-CE-${{ matrix.arch_suffix }}-Setup
+SolidCompression=yes
+WizardStyle=modern
+ArchitecturesAllowed=x86 x64compatible
+ArchitecturesInstallIn64BitMode=x64compatible
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Languages\English.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "./publish/${{ matrix.platform }}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "./publish/${{ matrix.platform }}\InkCanvasForClass.exe.config"; DestDir: "{app}"; Flags: ignoreversion
+Source: "./publish/${{ matrix.platform }}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+
+[Registry]
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
+
+[Icons]
+Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
+Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+"@
+ $scriptContent | Out-File -FilePath "installer-${{ matrix.platform }}.iss" -Encoding UTF8
+
+ - name: Create installer using Inno Setup
+ if: matrix.platform != 'ARM64'
+ run: |
+ mkdir -p ./installers
+ iscc installer-${{ matrix.platform }}.iss
+
+ - name: Create ARM64 portable package
+ if: matrix.platform == 'ARM64'
+ run: |
+ Compress-Archive -Path "./publish/${{ matrix.platform }}/*" -DestinationPath "./installers/InkCanvasForClass-CE-arm64-Portable.zip"
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: InkCanvas-${{ matrix.platform }}
+ path: |
+ ./publish/${{ matrix.platform }}/
+ ./installers/
+ retention-days: 30
+
+ create-release:
+ needs: build
+ runs-on: windows-latest
+ if: github.event_name == 'release'
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Download all artifacts
+ uses: actions/download-artifact@v4
+ with:
+ path: ./artifacts
+
+ - name: Get version from project
+ id: get_version
+ run: |
+ $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value })
+ echo "version=$version" >> $env:GITHUB_OUTPUT
+ echo "Version: $version"
+
+ - name: Prepare release files
+ run: |
+ # 创建发布目录
+ mkdir -p ./release
+
+ # 复制x86安装包
+ if (Test-Path "./artifacts/InkCanvas-x86/installers") {
+ Copy-Item "./artifacts/InkCanvas-x86/installers/*" -Destination "./release/" -Recurse
+ }
+
+ # 复制x64安装包
+ if (Test-Path "./artifacts/InkCanvas-x64/installers") {
+ Copy-Item "./artifacts/InkCanvas-x64/installers/*" -Destination "./release/" -Recurse
+ }
+
+ # 复制ARM64便携版
+ if (Test-Path "./artifacts/InkCanvas-ARM64/installers") {
+ Copy-Item "./artifacts/InkCanvas-ARM64/installers/*" -Destination "./release/" -Recurse
+ }
+
+ # 列出所有文件
+ Get-ChildItem -Path "./release" -Recurse | ForEach-Object { Write-Host "Release file: $($_.FullName)" }
+
+ - name: Create Release
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: v${{ steps.get_version.outputs.version }}
+ name: InkCanvasForClass CE v${{ steps.get_version.outputs.version }}
+ body: |
+ ## InkCanvasForClass CE v${{ steps.get_version.outputs.version }}
+
+ ### 下载
+ - **x86 (32位)**: 适用于32位Windows系统
+ - **x64 (64位)**: 适用于64位Windows系统
+ - **ARM64**: 适用于ARM64 Windows系统(便携版)
+
+ ### 安装说明
+ 1. 下载对应您系统架构的安装包
+ 2. 运行安装程序并按照提示完成安装
+ 3. ARM64版本为便携版,解压后直接运行即可
+
+ ### 系统要求
+ - Windows 7/10/11
+ - .NET Framework 4.7.2 或更高版本
+
+ files: |
+ ./release/*
+ draft: false
+ prerelease: false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file