Skip to content

拡張ライブラリの開発・デバッグ ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

拡張ライブラリ を作るときの、ビルド → 配置 → デバッグの流れをまとめます。プリザンターは DLL を起動時にしか読まないため、「ビルドしたら ExtendedLibraries にコピーして、プリザンターを再起動し、デバッガを付ける」の繰り返しになります。コピーは MSBuild のターゲットで自動化できます。

前提 ​

要件内容
.NET SDK本体と同じバージョン(1.5.8.1 は net10.0)
プリザンターのソース本体をプロジェクト参照する場合と、本体ごと起動してデバッグする場合に必要。プロセスにアタッチするだけなら公開済みバイナリでもよい
VS CodeC# Dev Kit または C# 拡張機能
Visual Studio2022 以降

プロジェクト構成 ​

text
MyExtendedLibrary/                 ← 拡張ライブラリのリポジトリ
├── MyExtendedLibrary.sln
├── MyExtendedLibrary/
│   ├── MyExtendedLibrary.csproj
│   ├── ExtendedLibrary.cs         ← 初期化クラス(任意)
│   ├── Controllers/
│   └── Api/
└── (../Implem.Pleasanter/)        ← 本体のソース(隣に置くかサブモジュール)

csproj ​

pdb を出力し、本体はプロジェクト参照だけにして出力にはコピーしません(Private="false"・ExcludeAssets="runtime")。本体と同じ名前の DLL を ExtendedLibraries に置くと本体側が優先され、バージョン違いでは実行時エラーの原因になるためです(読み込みで注意すること)。

xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>disable</Nullable>
    <!-- デバッグシンボルを pdb ファイルとして出力 -->
    <DebugType>portable</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference
      Include="..\Implem.Pleasanter\Implem.Pleasanter.csproj"
      Private="false"
      ExcludeAssets="runtime" />
  </ItemGroup>
</Project>

ビルド後に ExtendedLibraries へコピーする ​

ビルドのたびに DLL と pdb をプリザンターの実行フォルダの ExtendedLibraries へコピーするターゲットを足します。PleasanterOutputDir は環境に合わせて変えてください(Implem.Pleasanter.dll があるフォルダです)。

xml
<PropertyGroup>
  <PleasanterOutputDir>..\Implem.Pleasanter\bin\Debug\net10.0</PleasanterOutputDir>
</PropertyGroup>

<Target Name="CopyToExtendedLibraries" AfterTargets="Build">
  <ItemGroup>
    <ExtendedLibraryFiles Include="$(OutputPath)$(AssemblyName).dll" />
    <ExtendedLibraryFiles Include="$(OutputPath)$(AssemblyName).pdb" />
  </ItemGroup>
  <Copy
    SourceFiles="@(ExtendedLibraryFiles)"
    DestinationFolder="$(PleasanterOutputDir)\ExtendedLibraries"
    SkipUnchangedFiles="true" />
  <Message
    Text="拡張ライブラリを $(PleasanterOutputDir)\ExtendedLibraries にコピーしました"
    Importance="high" />
</Target>

SkipUnchangedFiles="true" で、変わっていないファイルのコピーは飛ばします。pdb も一緒にコピーしておくと、デバッガがブレークポイントを解決できます。

開発の流れ ​

図を読み込み中…

差し替えたら必ず再起動

DLL は起動時に Assembly.LoadFrom で読み込まれるだけなので、起動後に ExtendedLibraries の DLL を差し替えても実行中のプロセスには反映されません。ホットリロードも効きません。また読み込みには try-catch が無く、壊れた DLL を置くとプリザンターが起動しなくなります(Startup.cs)。

VS Code でデバッグする ​

方法 A: 起動中のプリザンターにアタッチする ​

プリザンターのソースが手元に無くても使えます。

  1. プリザンターを普通に起動する(dotnet run やサービス)
  2. 拡張ライブラリのフォルダを VS Code で開き、.vscode/launch.json を作る
  3. F5 でデバッグを始め、プロセスの一覧から Implem.Pleasanter を選ぶ
  4. 拡張ライブラリのコードにブレークポイントを置き、画面や API から拡張のエンドポイントを呼ぶ
json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Pleasanter",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}",
            "justMyCode": false,
            "symbolOptions": {
                "searchPaths": ["${workspaceFolder}/MyExtendedLibrary/bin/Debug/net10.0"]
            }
        }
    ]
}

シンボルが解決されない(ブレークポイントが白丸のまま)ときは、pdb が ExtendedLibraries に置かれているかを確かめ、そのフォルダも symbolOptions.searchPaths に足します。

方法 B: プリザンターごと起動する ​

本体のソースが隣にある場合は、マルチルートワークスペースで本体と拡張ライブラリを一緒に開き、F5 一つで「拡張ライブラリのビルド(とコピー)→ プリザンターの起動」まで行えます。毎回アタッチし直す手間がありません。

json
{
    "folders": [
        { "name": "MyExtendedLibrary", "path": "." },
        { "name": "Implem.Pleasanter", "path": "../Implem.Pleasanter" }
    ],
    "settings": {}
}
launch.json と tasks.json
json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Pleasanter",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build-extension",
            "program": "${workspaceFolder:Implem.Pleasanter}/bin/Debug/net10.0/Implem.Pleasanter.dll",
            "args": [],
            "cwd": "${workspaceFolder:Implem.Pleasanter}",
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            },
            "sourceFileMap": {
                "/": "${workspaceFolder:Implem.Pleasanter}"
            },
            "justMyCode": false,
            "symbolOptions": {
                "searchPaths": ["${workspaceFolder:Implem.Pleasanter}/bin/Debug/net10.0/ExtendedLibraries"]
            }
        }
    ],
    "compounds": [
        {
            "name": "Launch Pleasanter with Extension",
            "configurations": ["Launch Pleasanter"]
        }
    ]
}
json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build-extension",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build",
                "${workspaceFolder}/MyExtendedLibrary/MyExtendedLibrary.csproj",
                "--configuration",
                "Debug"
            ],
            "problemMatcher": "$msCompile",
            "group": "build",
            "presentation": {
                "reveal": "always",
                "panel": "new"
            }
        }
    ]
}
  1. development.code-workspace を VS Code で開く
  2. F5 で Launch Pleasanter with Extension を選ぶ
  3. 拡張ライブラリがビルドされ、DLL が ExtendedLibraries にコピーされたあと、プリザンターが起動して拡張ライブラリを読み込む

本体そのものを VS Code でビルド・起動する準備(DB・接続文字列など)は VS Code だけでビルド・デバッグする環境 を参照してください。

Visual Studio でデバッグする ​

方法 A: 同じソリューションで起動する ​

  1. 拡張ライブラリのソリューションを開き、「追加」→「既存のプロジェクト」で Implem.Pleasanter.csproj を追加する
  2. Implem.Pleasanter を「スタートアップ プロジェクトに設定」する
  3. 拡張ライブラリに上の CopyToExtendedLibraries ターゲットを入れておく
  4. ブレークポイントを置いて F5 で起動する
text
MyExtendedLibrary.sln
├── MyExtendedLibrary       ← 拡張ライブラリ(クラスライブラリ)
└── Implem.Pleasanter       ← 本体(スタートアップ プロジェクト)

プリザンターの起動には App_Data/Parameters などが要るため、プロジェクトのプロパティ →「デバッグ」→「作業ディレクトリ」に本体のフォルダを指定します。

方法 B: プロセスにアタッチする ​

  1. プリザンターを普通に起動する
  2. 「デバッグ」→「プロセスにアタッチ」(Ctrl+Alt+P)を開く
  3. 接続の種類に「マネージド(.NET Core、.NET 5+)」を選び、Implem.Pleasanter にアタッチする
  4. ブレークポイントを置いて拡張のエンドポイントを呼ぶ

シンボルが見つからないときは、「デバッグ」→「オプション」→「シンボル」で pdb のあるフォルダを追加します。

方法の比較 ​

VS Code A(アタッチ)VS Code B(一括起動)Visual Studio A(同じソリューション)Visual Studio B(アタッチ)
本体のソース不要必要必要不要
本体のコードで止めるソースが無ければ不可可可ソースが無ければ不可
準備の手間少ない中中少ない
再起動のたびのアタッチ必要不要不要必要
向いている場面すぐ確かめたいとき日々の開発本体と一緒に深く追うときすぐ確かめたいとき

関連ページ ​

変更履歴

第1版拡張ライブラリの読み込みと開発・デバッグ、拡張ヘッドリンク、SMTP の OAuth 送信の解説と、多言語・外部公開カレンダー・スレッド型サイトなどの改修・設計メモを追加