Skip to content

NuGetベースのプラグイン導入UIを実装する - #615

Open
Freeesia with Copilot wants to merge 45 commits into
masterfrom
copilot/implement-nuget-plugin-ui
Open

NuGetベースのプラグイン導入UIを実装する#615
Freeesia with Copilot wants to merge 45 commits into
masterfrom
copilot/implement-nuget-plugin-ui

Conversation

Copilot AI commented May 2, 2026

Copy link
Copy Markdown
Contributor

Closes #614

WindowTranslatorアプリ内からNuGet上のプラグインを検索・インストール・更新・アンインストールできるようにします。独自の plugin.json やプラグインギャラリーは導入せず、既存のプラグインインターフェースと FolderPluginCatalog による読み込みを維持します。

NuGet検索と互換性

  • NuGet Client SDKのV3リソースを使い、windowtranslator-plugin タグを持つパッケージを検索
  • WindowTranslator.Abstractions への直接依存があり、現在のホスト版と依存バージョン範囲が互換なバージョンだけを表示・導入対象にする
  • リリース版とプレリリース版を検索し、プラグインごとに利用するチャネルを選択可能
  • 検索情報は BackgroundService だけを起点として、起動時と1時間ごとに更新。UIは保持済みのスナップショットと更新通知を表示
  • 一部パッケージのメタデータ取得だけが失敗した場合は、取得できたパッケージを残しつつ検索エラーをUIへ通知
  • READMEはNuGetメタデータのURLから、30秒タイムアウトを設定した名前付きHttpClientで取得
  • NuGet検索・メタデータ・nupkg取得の通信はNuGet Client SDK側のHTTP処理を利用

インストール・更新・アンインストール

  • .nupkgをダウンロードし、対応するTFMのlibアセットと、実行中のRID・win・anyに対応するruntimes配下のmanaged/nativeアセットを配置
  • NuGetのバージョン範囲を考慮して実行時依存パッケージを解決
  • NuGet管理プラグインの配置先は %USERPROFILE%.wt\nuget-plugins{PackageId}\
  • 手動配置プラグインの %USERPROFILE%.wt\plugins\ とは管理領域を分離し、NuGetの操作では変更しない
  • インストール済みパッケージ、バージョン、導入時のWindowTranslatorメジャーバージョンを nuget-manifest.json で管理
  • インストール・更新は .operations 配下の作業領域と操作ジャーナルを使い、対象フォルダの配置とmanifest更新が両方成功した後に完了扱いにする
  • 完了前にアプリが終了したインストール・更新は次回起動時に旧フォルダと旧manifestへ戻し、完了後に後片付けだけが残った操作は新状態を維持する
  • 通常の配置・manifest更新失敗時も以前の状態へロールバック
  • アンインストールは先にmanifestから対象を削除し、その後に管理フォルダの実体を即時削除。操作ジャーナルや退避領域は作成しない
  • 実行中のプラグインは一時コピーから読み込まれているため、更新・アンインストールの反映後にUIからWindowTranslatorを再起動可能
  • WindowTranslatorのメジャーバージョンが変わった既存プラグインは非互換として扱う
  • DISABLE_PLUGIN_COMPATIBILITY_VALIDATION 定義時は互換性検証を無効化し、Debugビルドではこの定義を常に付与

プラグインの読み込み

  • 起動時に nuget-manifest.json へ登録された、現在のホストメジャーバージョンと互換なPackageIdのフォルダだけを %TEMP%\WindowTranslator\nuget-plugins へ差分同期してから FolderPluginCatalog で読み込み
  • 変更されたファイルだけをコピーし、manifestの対象から外れたファイルとディレクトリだけを一時コピーから削除
  • manifestが存在しない、読み込めない、または一覧にないフォルダは読み込まない
  • 復旧できなかった未完了操作のPackageIdは読み込み対象から除外
  • 管理フォルダ内のDLLを直接読み込まないため、実行中のファイルロックに影響されず更新・削除可能
  • 同じアセンブリ単純名のNuGet版とフォールバック版がある場合はNuGet版のアセンブリを優先
  • 選択したアセンブリが提供するすべてのプラグイン型を維持し、異なるアセンブリにある同名型は排除しない
  • NuGet版がないプラグインは従来どおり同梱版または手動配置版を利用

UI

  • 設定画面の3番目に「プラグイン」タブを追加
  • パッケージ一覧、詳細、README、ライセンス、プロジェクトURLを表示
  • 各プラグインの「プレリリース」チェックでリリース版/プレリリース版を個別に選択
  • プレリリース版だけが存在するパッケージは、チェックを入れるまでインストール不可
  • インストール済み・更新可能な状態を表示
  • インストール、更新、アンインストール、進捗、エラー、再起動に対応

設定の扱い

  • SelectedPlugins や PluginParams だけを根拠にNuGetパッケージを特定・自動インストールしない
  • 読み込まれていないプラグインのパラメータは無視
  • 読み込まれたプラグインでもパラメータをデシリアライズできない場合は、その値を無視して既定値を維持
  • 選択中のプラグインが削除されても起動不能にしない

パッケージ公開と開発者向け整備

  • リポジトリ内のpack可能な既存プラグインへ、既存タグを維持したまま windowtranslator-plugin タグとREADMEを設定

  • 外部プラグインは次のタグを付与し、既存のプラグインIFを実装して WindowTranslator.Abstractions へ依存させる

    $(PackageTags);windowtranslator-plugin

  • vタグのpush時に、タグから検証・抽出したSemVerをパッケージ版としてNuGetへ公開

  • docs/plugin.md に作成・公開・インストール・プレリリース選択手順を追加

  • Plugins/WindowTranslator.Plugin.DeepLTranslatePlugin/ を外部プラグインの実装例として利用可能

検証

  • WindowTranslator.Tests Debug: 95件成功
  • WindowTranslator.Tests Release: 95件成功
  • NuGet通信はインメモリのテストリソースで検証し、NuGet.org接続を必要とするテストは実行していない
  • 未完了インストールの旧状態への復旧、完了済みインストールの新状態維持、完了済み操作の後処理失敗時もロード対象を維持することをテスト
  • 22個のresxすべてでプラグイン管理・再起動用リソースが定義され、XMLとして読み込めることを確認
  • git diff --check 成功

Copilot AI linked an issue May 2, 2026 that may be closed by this pull request
28 tasks
Copilot AI changed the title [WIP] Implement UI for NuGet-based plugin installation NuGetベースのプラグイン導入UIを実装する May 2, 2026
Copilot AI requested a review from Freeesia May 2, 2026 14:48
@Freeesia

Freeesia commented May 2, 2026

Copy link
Copy Markdown
Owner

@copilot

既存のプラグインは全てNuget対応して。
また、以下のプラグインをアプリに含めないようにして。ただし、互換性のために設定で利用される設定になっていれば起動時にインストールするようにして。

  • FoM
  • Plamo
  • GithubCopilot
  • DeepL
  • GoogleAI
  • GoogleAppScript
  • LLM
  • TesseractOcr

削除や更新対応のため、プラグインは読み込む前にフォルダごと一時フォルダにコピーして。
プラグインライブラリのカタログクラスを継承した方がいいかも。

Agent-Logs-Url: https://github.com/Freeesia/WindowTranslator/sessions/49085e31-7c44-4f11-82e0-fe40172b8447

Co-authored-by: Freeesia <9002657+Freeesia@users.noreply.github.com>
Comment thread WindowTranslator/Modules/PluginStore/NuGetPluginOperation.cs
Comment thread .github/workflows/dotnet-package.yml
Comment thread .github/workflows/dotnet-desktop.yml
Comment thread .github/workflows/dotnet-desktop.yml Outdated
Comment thread .github/workflows/dotnet-package.yml Outdated
Comment thread .github/workflows/dotnet-package.yml Outdated
Comment thread Plugins/Directory.Build.props Outdated
Comment thread Plugins/Directory.Build.targets Outdated
Comment thread Plugins/Directory.Build.targets Outdated
Comment thread Plugins/Directory.Build.targets Outdated
Comment thread Plugins/Directory.Build.targets Outdated
Comment thread Plugins/Directory.Build.targets Outdated
Comment thread ColorThief/ColorThief/ColorThief.csproj
Comment thread Plugins/WindowTranslator.Plugins.proj
Comment thread WindowTranslator.Abstractions/WindowTranslator.Abstractions.csproj
Comment thread WindowTranslator/Program.cs Outdated
@Freeesia

Copy link
Copy Markdown
Owner

@copilot このブランチのマージ競合を解決してください。

Co-authored-by: Freeesia <9002657+Freeesia@users.noreply.github.com>

Copilot AI commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot このブランチのマージ競合を解決してください。

マージ競合を解決しました(コミット 3adf2c2)。

  • .github/workflows/dotnet-desktop.yml: origin/master で追加された CUDA toolkit セットアップステップを受け入れました
  • WindowTranslator.Abstractions/UserSettings.cs: このブランチで追加した IsEnableAutoTargetHidePluginStoreDisclaimer プロパティを保持しました

Co-authored-by: Freeesia <9002657+Freeesia@users.noreply.github.com>
Co-authored-by: Freeesia <9002657+Freeesia@users.noreply.github.com>
@Freeesia

Copy link
Copy Markdown
Owner
  • プラグインの免責事項の表示を消すオプションがプラグインインストール後の再起動で無効化される
    • オプションをマニフェストファイルに記録するようにして、オプション有効化したタイミングで保存する
  • インストール時のProgressRingがほぼ動かない
    • 適切なタイミングで進める
    • 少なくともインストール後に100%にする
    • そもそも0-1なのか0-100なのかの認識が間違っているかも
  • プラグインインストール後の再起動でプラグインが読み込まれない
  • 再起動待ちの時は設定ダイアログの「OK」「キャンセル」の左に「プラグイン読み込み」ボタンを付けて再起動できるようにする

Comment thread WindowTranslator/Modules/Settings/AllSettingsDialog.xaml Outdated
Comment thread WindowTranslator/Modules/PluginStore/PluginStoreViewModel.cs Outdated
@Freeesia

Copy link
Copy Markdown
Owner

プラグインインストール後の再起動でプラグインが読み込まれない

これは、再起動で読み込まれないのではなく、そもそもインストールしたプラグインが読み込まれない。
(デバッグ起動時)

再起動時の対策は戻して、インストールしたプラグインが読み込まれない問題の原因特定と修正して。

Copy link
Copy Markdown
Owner

原因を確認して修正しました。

デバッグ版ホストの WindowTranslator.AbstractionsAssemblyVersion=0.0.0.0 ですが、公開済みプラグインはNuGetビルド時のバージョン(例: 0.9.23.1)を要求します。PluginFrameworkがその要求バージョンのまま既定のロードコンテキストからホスト側Abstractionsを読み込もうとするため、デバッグ起動では FileNotFoundException となり、プラグインが読み込まれていませんでした。

デバッグ時のみ、要求バージョンにかかわらず既に読み込まれているホスト側Abstractionsを返すよう修正しました。再起動側へ追加の回避処理は入れず、実際のアセンブリ解決を修正しています。

反映: c47cbb0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NuGetベースのプラグイン導入UIを実装する

3 participants