tag:crieit.net,2005:https://crieit.net/users/RedCol/feed
RedColの投稿 - Crieit
CrieitでユーザーRedColによる最近の投稿
2022-05-26T20:41:56+09:00
https://crieit.net/users/RedCol/feed
tag:crieit.net,2005:PublicArticle/18198
2022-05-26T20:41:56+09:00
2022-05-26T20:41:56+09:00
https://crieit.net/posts/aka-tool-batlauncher
PowerShell:指定フォルダのbatを実行するLauncherを作ってみた
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>お仕事とかでテスト用batとか作ってしょっちゅうたたくけどいちいちコマンドプロンプトに打つのも面倒なので画面のはじっこにでもbat実行用のLauncherでも置いとけばいいかなと思って作ってみた。<br />
最初は適当にexe作ろうと思ったけどたまにはPowerShellでForm作るの復習がてらやってみようってことで昼休みに作ってたらまんまと罠にはまって一旦諦め。<br />
解決はしたものの悔しさと絶対覚えてられない自身があったので記事に残す。</p>
<h1 id="やりたいこと"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8">やりたいこと</a></h1>
<ul>
<li>引数で渡されたPathにある.batファイルをそれぞれボタンコントロールにして一列に並べる。</li>
<li>ボタンをクリックすると対応するbatを実行する</li>
<li>後ろに隠れると不便だからTopMost</li>
<li>batファイルがなければエラーメッセージでもだして終了</li>
</ul>
<h1 id="単純にFormの話"><a href="#%E5%8D%98%E7%B4%94%E3%81%ABForm%E3%81%AE%E8%A9%B1">単純にFormの話</a></h1>
<p>最初のおまじないさえ知っておけばそんなに難しくない</p>
<p>こういうの(アセンブリ)使うよって教えてあげて</p>
<pre><code>Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
</code></pre>
<p>Form(外側)作ってあげて</p>
<pre><code>$Form = New-Object System.Windows.Forms.Form
$Form.Text = "BatToolLauncher"
$Form.Width = 180
$Form.Height = $BatList.Count*30 + 50
$Form.TopMost = $true
</code></pre>
<p>ボタンを配置する</p>
<pre><code>$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Point(0,0)
$Button.Top = $Button.Top + $i * 30
$Button.Size = New-Object System.Drawing.Size(160,30)
$Button.Text = $x.BaseName
$Form.Controls.Add($Button)
</code></pre>
<p>※$BatListはbatの一覧(Get-ChildItemの結果)<br />
※$xは$BatListをforeachで回した時の一時変数</p>
<h1 id="ボタンクリック時の挙動を設定する(今回の鬼門)"><a href="#%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E6%99%82%E3%81%AE%E6%8C%99%E5%8B%95%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%28%E4%BB%8A%E5%9B%9E%E3%81%AE%E9%AC%BC%E9%96%80%29">ボタンクリック時の挙動を設定する(今回の鬼門)</a></h1>
<p>ボタンクリック時の挙動を書くことだけは簡単。<br />
「Add_イベント」の形で定義してあげればいい。クリックイベントなら下の{}の中に書けばいい。</p>
<pre><code>$Button.Add_Click({})
</code></pre>
<p>簡単。なはずだった。<br />
とにもかくにも失敗例↓</p>
<pre><code>$Button.Add_Click({Start-Process -WindowStyle Hidden $x.FullName})
</code></pre>
<p>これは$x.FullNameでbatのフルパスが入るからそいつをStart-Processするだけ簡単だよね、と思って頭を抱えたもの。<br />
何が起こるかというと、実際のクリック時の$xを参照してくれる。foreachでぐるぐる回していたので、$xが指すのは最後のbat。つまり、どのボタンを押しても最後のbatファイルが実行される。<br />
というわけで半日かけて試行錯誤・調査して解決策↓</p>
<pre><code>$Button.Add_Click({Start-Process -WindowStyle Hidden $x.FullName}.GetNewClosure())
</code></pre>
<p>GetNewClosure()<br />
を書くことでこの{}で囲まれた部分はスクリプトブロックじゃなくてクロージャだよ、となるらしい。今回の話に沿わせるとこの行を書いた時点の変数の内容でFixしてくれるらしい。<br />
ちょっと説明の言葉が怪しい自覚はある。</p>
<h1 id="スクリプト全体"><a href="#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E5%85%A8%E4%BD%93">スクリプト全体</a></h1>
<p>結果的にこんな感じ。</p>
<pre><code>Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
if($args.Length -gt 0)
{
$TargetDir = $args[0]
}
else
{
$MyPath = $MyInvocation.MyCommand.Path
$TargetDir = Split-Path -Parent $MyPath
}
# batファイルのリスト作成
$BatList = Get-ChildItem $TargetDir -Filter "*.bat"
if($BatList -eq $null)
{
[System.Windows.Forms.MessageBox]::Show("no bat files", "Error")
return
}
# Form作成
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "BatToolLauncher"
$Form.Width = 180
$Form.Height = $BatList.Count*30 + 50
$Form.TopMost = $true
# ボタン作成
$i = 0
foreach($x in $BatList)
{
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Point(0,0)
$Button.Top = $Button.Top + $i * 30
$Button.Size = New-Object System.Drawing.Size(160,30)
$Button.Text = $x.BaseName
# GetNewClosure様をたたえる!
$Button.Add_Click({Start-Process -WindowStyle Hidden $x.FullName}.GetNewClosure())
$Form.Controls.Add($Button)
$i++
}
# 表示
$Form.ShowDialog()
</code></pre>
<h1 id="おまけ"><a href="#%E3%81%8A%E3%81%BE%E3%81%91">おまけ</a></h1>
<p>ps1ファイルってそのままたたけないのでいつも汎用性持たせて作ってるbat</p>
<pre><code>powershell -ExecutionPolicy RemoteSigned %~dpn0.ps1 %*
</code></pre>
<p>同じ場所にある同名ps1を実行するbat<br />
いつもの使いまわしファイルがどこかにいったので久しぶりに手書きしたけどだいたいこんなだったはず。</p>
RedCol
tag:crieit.net,2005:PublicArticle/17959
2022-01-28T19:10:57+09:00
2022-01-28T19:12:24+09:00
https://crieit.net/posts/aka-bat-1
バッチ書くときにしょっちゅう調べなおすこと
<h1 id="パラメータ"><a href="#%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF">パラメータ</a></h1>
<p>%0がバッチ自身で%1-nが引数なのは当然として、%~dp0とかの話。</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>修飾子</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td>%~0</td>
<td>ダブルクォートをとっぱらう</td>
</tr>
<tr>
<td>%~d0</td>
<td>ドライブ文字だけ</td>
</tr>
<tr>
<td>%~p0</td>
<td>ドライブ文字の後のパスだけ(ファイル名は含まない)</td>
</tr>
<tr>
<td>%~f0</td>
<td>フルパス</td>
</tr>
<tr>
<td>%~n0</td>
<td>ファイル名だけ(拡張子は含まない)</td>
</tr>
<tr>
<td>%~x0</td>
<td>拡張子だけ</td>
</tr>
<tr>
<td>%~a0</td>
<td>ファイル属性だけ</td>
</tr>
<tr>
<td>%~t0</td>
<td>ファイル時刻だけ</td>
</tr>
<tr>
<td>%~z0</td>
<td>ファイルサイズだけ</td>
</tr>
<tr>
<td>%~dp0</td>
<td>[応用]ドライブ含むバッチのあるディレクトリ</td>
</tr>
<tr>
<td>%~dpn0.ps1</td>
<td>[応用]同パス同名だけど拡張子がps1</td>
</tr>
</tbody>
</table></div>
<h1 id="対話入力"><a href="#%E5%AF%BE%E8%A9%B1%E5%85%A5%E5%8A%9B">対話入力</a></h1>
<p>/pオプション。気を付けるべきはsetは変数と=の間に隙間あけちゃだめってとこ。</p>
<pre><code>set /p hoge="Input:"
echo %hoge%
</code></pre>
<h1 id="遅延環境変数"><a href="#%E9%81%85%E5%BB%B6%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0">遅延環境変数</a></h1>
<p>詳しい説明はどこかに任せる。<br />
要はifとかforとかの括弧の中は1行として扱われるからその中で変化した変数を扱いたい時にこれを使う。<br />
※なにが”遅延”なのかいまだに理解できていない。<br />
ポイントは最初のおまじないとエクスクラメーションマークでくくることくらい。<br />
最初のおまじないの言葉をよく忘れる。間にスペースがないから覚えにくいのだと思う。<br />
「enable delayed expansion」</p>
<pre><code>setlocal enabledelayedexpansion
if "%hoge%"=="" (
set result="karappo"
echo !result!
)
</code></pre>
<h1 id="権限昇格の技"><a href="#%E6%A8%A9%E9%99%90%E6%98%87%E6%A0%BC%E3%81%AE%E6%8A%80">権限昇格の技</a></h1>
<p>PowerShellさんまじですごい。<br />
Start-Processに-Verbっていうのがあって色々ユーザ視点でできるけどその中に管理者として実行がある。それがrunas。あとは知ってることの組み合わせ。</p>
<pre><code>@echo off
if not "%1%"=="admin" (
PowerShell -command "Start-Process -Verb runas -FilePath %~f0 -ArgumentList 'admin'"
) else (
echo Start Run As Administrator!
pause
)
</code></pre>
<p>上記例では自身を管理者権限で呼び出している。無理やり引数にフラグもたせたけどもっとスマートな方法があるかも。</p>
<h1 id="気が向いたら追記する"><a href="#%E6%B0%97%E3%81%8C%E5%90%91%E3%81%84%E3%81%9F%E3%82%89%E8%BF%BD%E8%A8%98%E3%81%99%E3%82%8B">気が向いたら追記する</a></h1>
RedCol
tag:crieit.net,2005:PublicArticle/17958
2022-01-28T18:32:09+09:00
2022-01-28T18:32:09+09:00
https://crieit.net/posts/aka-win-sysconf-1
OSの設定をPowershellで変える(言語編)
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>多国語の対応とかしてると確認のためにいちいちシステム言語を切り替えて云々が発生してうっとおしいのでバッチにしてしまえ、たぶんPowerShellでできるはずだ、ということで調べた結果を垂れ流す。<br />
なお、システム設定いじくるので管理者として実行してあげる必要がある。<br />
それも面倒なので権限昇格するようにバッチで行う。(そのうち別記事で書く)</p>
<h1 id="サポート言語の追加"><a href="#%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E8%A8%80%E8%AA%9E%E3%81%AE%E8%BF%BD%E5%8A%A0">サポート言語の追加</a></h1>
<p>[Windows設定]→[時刻と言語]→[言語]のページの下の方の[言語の追加]。</p>
<h2 id="Get-WinUserLanguageList/Set-WinUserLanguageList"><a href="#Get-WinUserLanguageList%2FSet-WinUserLanguageList">Get-WinUserLanguageList/Set-WinUserLanguageList</a></h2>
<p>Get~で現在のサポート言語のリストをとってくる<br />
Set~でサポート言語リストをセットする<br />
ので<br />
1.Getする<br />
2.追加する(言語コードをAdd)<br />
3.Setする<br />
でいける</p>
<p>例えばドイツ語なら</p>
<pre><code>$CurrList = Get-WinUserLanguageList
$CurrList.Add("de-DE")
Set-WinUserLanguageList $CurrList -Force
</code></pre>
<p>-Forceは自動化したいから。ないと確認メッセージが出ます。</p>
<h1 id="地域設定(形式)"><a href="#%E5%9C%B0%E5%9F%9F%E8%A8%AD%E5%AE%9A%28%E5%BD%A2%E5%BC%8F%29">地域設定(形式)</a></h1>
<p>[Windows設定]→[時刻と言語]→[地域]のページの2こめくらい。</p>
<h2 id="Get-Culture/Set-Culture"><a href="#Get-Culture%2FSet-Culture">Get-Culture/Set-Culture</a></h2>
<p>ただ言語デフォルトに変更したいだけならSet-Cultureで言語コードを渡せばいい。<br />
だけど言語デフォルトでありがちな罠の小数点(たまにカンマの国がある)を変更したいなら<br />
1.Set 言語デフォルト<br />
2.Get<br />
3.編集<br />
4.Set 編集したの<br />
という手順になるが、どうも1の直後に2を呼ぶと反映されてなかったのでps1ファイルを分けた。</p>
<pre><code># ChangeCulture_1.ps1
Set-Culture "de-DE"
</code></pre>
<pre><code># ChangeCulture_2.ps1
$Cult = Get-Culture
$Cult.NumberFormat.NumberDecimalSeparator = "."
Set-Culture $Cult
</code></pre>
<h1 id="システムロケール"><a href="#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB">システムロケール</a></h1>
<p>[Windows設定]→[時刻と言語]→[地域]→[関連設定:日付、時刻、地域の追加設定]→[地域]→[管理]タブ→[Unicode対応ではないプログラムの言語]<br />
※遠い、正直コントロールパネル出した方が早く着く</p>
<h2 id="Get-WinSystemLocale/Set-WinSystemLocale"><a href="#Get-WinSystemLocale%2FSet-WinSystemLocale">Get-WinSystemLocale/Set-WinSystemLocale</a></h2>
<p>確認したいならGetで。Setで言語コードを入れれば終わり。</p>
<pre><code>Set-WinSystemLocale "de-DE"
</code></pre>
<p>再起動は必須なのでお好みに合わせて<br />
Restart-System<br />
をスクリプトに含めるなり、そこは手でやるなりご自由に。</p>
<p>カンタン!</p>
RedCol
tag:crieit.net,2005:PublicArticle/17957
2022-01-27T18:42:45+09:00
2022-01-27T18:42:45+09:00
https://crieit.net/posts/aka-lang-country
言語コードと国コード
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>仕事してると多国語の対応とかでてきて、ja-JPとかen-USとかいうコードを扱うことがある。<br />
意味わからず使っていた時代を反省して知ってることを書き出しておく。</p>
<h1 id="構造"><a href="#%E6%A7%8B%E9%80%A0">構造</a></h1>
<p>そもそもja-JP、en-USというのはISOの言語コードと国名コードの組み合わせ<br />
<code>言語ー国名</code><br />
の順。<br />
例えば</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>コード</th>
<th>言語</th>
<th>国</th>
</tr>
</thead>
<tbody>
<tr>
<td>ja-JP</td>
<td>日本語</td>
<td>日本国</td>
</tr>
<tr>
<td>en-US</td>
<td>英語</td>
<td>アメリカ合衆国</td>
</tr>
<tr>
<td>de-DE</td>
<td>ドイツ語</td>
<td>ドイツ</td>
</tr>
<tr>
<td>de-CH</td>
<td>ドイツ語</td>
<td>スイス</td>
</tr>
<tr>
<td>fr-CH</td>
<td>フランス語</td>
<td>スイス</td>
</tr>
</tbody>
</table></div>
<p>とか日本にいると馴染みが薄いけど<br />
同じ言葉を違う国で<br />
違う言葉を同じ国で<br />
なんて普通にある(スイスとか有名ですよね)</p>
<h1 id="言語コード(ISO 639)"><a href="#%E8%A8%80%E8%AA%9E%E3%82%B3%E3%83%BC%E3%83%89%28ISO+639%29">言語コード(ISO 639)</a></h1>
<p>言語コードを規定している国際規格。<br />
ISO 639-1にアルファベット2文字のコード<br />
ISO 639-2にアルファベット3文字のコード<br />
を規定している<br />
幸いなのか2文字しか使ったことがないので3文字の出番はどれくらいあるのか不明。</p>
<h1 id="国名コード(ISO 3166-1)"><a href="#%E5%9B%BD%E5%90%8D%E3%82%B3%E3%83%BC%E3%83%89%28ISO+3166-1%29">国名コード(ISO 3166-1)</a></h1>
<p>国名コードを規定している国際規格。<br />
ISO 3166全体は国含むその下の州や都道府県といった地域全体を規定する存在。<br />
ISO 3166-2は州や都道府県らしい。</p>
<p>ちなみにこちらは</p>
<ul>
<li>ISO 3166-1 alpha-2 : 2文字</li>
<li>ISO 3166-1 alpha-3 : 3文字</li>
<li>ISO 3166-1 numeric : 3桁の数字</li>
</ul>
<p>といった風に1の中にパターンが持たされている</p>
<h1 id="忘れやすいコード(個人の感想です)"><a href="#%E5%BF%98%E3%82%8C%E3%82%84%E3%81%99%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%28%E5%80%8B%E4%BA%BA%E3%81%AE%E6%84%9F%E6%83%B3%E3%81%A7%E3%81%99%29">忘れやすいコード(個人の感想です)</a></h1>
<p>追加された順番とか昔の国名の影響とかなのか個人的になじめずにいつもなんだっけとなるコード覚書。</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>コード</th>
<th>言語</th>
<th>国</th>
<th>備考</th>
</tr>
</thead>
<tbody>
<tr>
<td>de-DE</td>
<td>ドイツ語</td>
<td>ドイツ</td>
<td>ドイツ語=Deutsch</td>
</tr>
<tr>
<td>da-DK</td>
<td>デンマーク語</td>
<td>デンマーク</td>
<td>de-DEと混同しがち、デンマーク語=dansk</td>
</tr>
<tr>
<td>sv-SE</td>
<td>スウェーデン語</td>
<td>スウェーデン</td>
<td>swはスワヒリ語でseは北部サーミ語らしい</td>
</tr>
<tr>
<td>nl-NL</td>
<td>オランダ語</td>
<td>オランダ</td>
<td>オランダ=Netherlands</td>
</tr>
<tr>
<td>no-NO</td>
<td>ノルウェー語</td>
<td>ノルウェー</td>
<td>nl-NLと混同しがち</td>
</tr>
<tr>
<td>zh-CN</td>
<td>中国語</td>
<td>中国</td>
<td>CHかと思いきやCN。言語も想像しにくいzh</td>
</tr>
</tbody>
</table></div>
RedCol
tag:crieit.net,2005:PublicArticle/17686
2021-09-26T19:49:37+09:00
2021-09-26T19:54:52+09:00
https://crieit.net/posts/aka-dicom-kiso1
これだけは知っておきたいDICOM
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>DICOMとは何ぞやとか成り立ちとかはおいておいて、DICOM勉強しはじめたときに手助けになるようなことを書いておく</p>
<h1 id="お勉強用資料"><a href="#%E3%81%8A%E5%8B%89%E5%BC%B7%E7%94%A8%E8%B3%87%E6%96%99">お勉強用資料</a></h1>
<h2><a target="_blank" rel="nofollow noopener" href="https://www.dclunie.com/dicom-status/status.html">DICOM Standard Status</a></h2>
<p>最近は年間5回(a→b→c→d→e)更新される<br />
現時点(2021年9月)で1~22章(9,13はリタイア)まであり、気が付いたら増えてたりする。<br />
よく見かけるPS3.Xという書き方のXは章番号を表している。ちなみに3の方はDICOMのVersionだが長らく変わっていない。</p>
<p>とても全部は読めないのでおそらく大半の人が最初に必要になる、3~5章を眺めるといい。<br />
こんな情報が知りたいけどどこ見たらいいのかわからない場合は以下参考。</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>知りたいこと</th>
<th>章番号</th>
</tr>
</thead>
<tbody>
<tr>
<td>画像種・操作ごとに必要なタグが知りたい</td>
<td>3章(情報オブジェクト定義)</td>
</tr>
<tr>
<td>画像種・操作の組み合わせが知りたい</td>
<td>4章(サービスクラス)</td>
</tr>
<tr>
<td>VRの意味、DICOMデータの構造、バイナリデータの持ち方、文字コードの表し方、画像自体・輝度の計算が知りたい</td>
<td>5章(データ構造と符号化)</td>
</tr>
<tr>
<td>タグNo、タグ名、VR、VMが知りたい</td>
<td>6章(データ辞書)</td>
</tr>
<tr>
<td>DICOMメッセージのやり取りが知りたい</td>
<td>7章(メッセージ交換)</td>
</tr>
<tr>
<td>匿名化の対象や方法が知りたい</td>
<td>15章(セキュリティ辞書)</td>
</tr>
<tr>
<td>造影剤などコードとその意味の定義が知りたい</td>
<td>16章(コンテンツマッピング)</td>
</tr>
</tbody>
</table></div>
<h2><a target="_blank" rel="nofollow noopener" href="https://www.jira-net.or.jp/dicom/index.html">JIRA DICOMの世界</a></h2>
<p>DICOM規格の和訳(但し結構古いので注意)や、勉強会の資料などが置いてある。<br />
「現場でDICOM接続に慌てないための知識」とか割と役立つので初心者は一度目を通しておくとよい。</p>
<h1 id="DICOM通信はオブジェクト+サービスの組み合わせ"><a href="#DICOM%E9%80%9A%E4%BF%A1%E3%81%AF%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%EF%BC%8B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B">DICOM通信はオブジェクト+サービスの組み合わせ</a></h1>
<p>オブジェクトをどうする(サービス)かの組み合わせになる。まずはオブジェクトとサービス(クラス)の説明から。</p>
<h2 id="オブジェクト(IOD=Information Object Definitions)"><a href="#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%28IOD%EF%BC%9DInformation+Object+Definitions%29">オブジェクト(IOD=Information Object Definitions)</a></h2>
<p>要するに扱うもの。<br />
MR画像やCT画像といったもの。<br />
* MR Image IOD Modules<br />
* CT Image IOD Modules<br />
* Enhanced MR Image IOD Modules<br />
* SC Image IOD Modules</p>
<p>など。<br />
Modulesと複数形になっている通り一つのオブジェクトを複数のモジュールで構成している。<br />
モジュールはまた複数のタグで構成されている。<br />
例えばMR画像に関してはPS3.3のA4.3にモジュール群が書かれているが、各モジュールのReference列の節に飛ぶことで詳細なタグ情報がわかる。<br />
※基本、DICOM規格読むときは飛びまくるので迷子にならないように注意すること。</p>
<p>つまりこういう組み合わせ。<br />
<div class="table-responsive"><table>
<thead>
<tr>
<th>IOD</th>
<th>Module</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
<tr>
<td>MR Image IOD Modules</td>
<td>Patient</td>
<td>Patient's Name(0010,0010)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Patient ID(0010,0020)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>…</td>
</tr>
<tr>
<td></td>
<td>General Studies</td>
<td>Study Instance UID(0020,000D)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Study Date(0008,0020)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>…</td>
</tr>
<tr>
<td></td>
<td>…</td>
<td>…</td>
</tr>
</tbody>
</table></div></p>
<p>ちなみにIODの表のUsage欄に書かれている記号はA1.3までさかのぼると書いてある。<br />
* Mandatory (see Section A.1.3.1), abbreviated M<br />
* Conditional (see Section A.1.3.2), abbreviated C<br />
* User Option (see Section A.1.3.3), abbreviated U</p>
<p>こういうのもどこに書いてあるかわからなくなることが多々あるので、次に見つけたらメモしておこうと毎回思って忘れる。</p>
<h2 id="サービスクラス"><a href="#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%AF%E3%83%A9%E3%82%B9">サービスクラス</a></h2>
<p>上記オブジェクトを「どうするか」の部分。<br />
分かりやすいので言えば、「転送する」「印刷する」<br />
* Storage Management Service Ckass:転送する<br />
* Print Management Service Class:印刷<br />
* Modality Worklist Management Service Class(MWM):検査オーダ受信</p>
<p>など。もっといっぱいあるが一個ずつ説明が重いので別で説明する、つもり。</p>
<h2 id="オブジェクト+サービスの組み合わせ(SOP=Service Object Pair)"><a href="#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%2B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%28SOP%3DService+Object+Pair%29">オブジェクト+サービスの組み合わせ(SOP=Service Object Pair)</a></h2>
<p>オブジェクトとどうする(サービス)かの組み合わせのことをSOP Classと表す。<br />
SOP Class UID(0008,0016)はその組み合わせを示すユニークなIDとなり、通信時に必須となる。<br />
要はこれからこういう通信を行うよ、と伝えるのにDICOM共通のIDがあると一発で伝えるため。<br />
SOP Instance UID(0008,0018)はあくまでインスタンスなので個別につける。但しUID=ユニークなIDなので1画像ずつ違うこと、上位の方はルールがあるので従う。それについてもそのうち書くかもしれない。</p>
<h1 id="SCUとSCP"><a href="#SCU%E3%81%A8SCP">SCUとSCP</a></h1>
<p>サービスを使いたい人とそれを提供する人。別の言い方をすればメッセージを投げる人と受け取る人。<br />
* SCU=Service Class User=サービスを使う人<br />
* SCP=Service Class Provider=サービスを提供する人</p>
<p>Storage SCU(画像を送る人)、Storage SCP(画像を受け取る人)のように表される、慣れるまではどっちがどっちかよく忘れるのでわからなくなったら都度確認すること。</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>Service</th>
<th>SCU</th>
<th>SCP</th>
</tr>
</thead>
<tbody>
<tr>
<td>Storage</td>
<td>画像を転送したい(する)人(Modality)</td>
<td>画像を受け取る人(PACS)</td>
</tr>
<tr>
<td>Print</td>
<td>画像を印刷したい人(Modality)</td>
<td>画像を受け取り印刷する人(Printer)</td>
</tr>
<tr>
<td>MWM</td>
<td>検査オーダがないか知りたい人(Modality)</td>
<td>検査オーダを返す人(RIS)</td>
</tr>
</tbody>
</table></div>
<h1 id="DICOM通信は3ステップ"><a href="#DICOM%E9%80%9A%E4%BF%A1%E3%81%AF3%E3%82%B9%E3%83%86%E3%83%83%E3%83%97">DICOM通信は3ステップ</a></h1>
<p>DICOMの通信は大雑把に3ステップ</p>
<ol>
<li>アソシエーション確立(相互認証)</li>
<li>データ通信(オブジェクト交換)</li>
<li>アソシエーション解放(エラーの確認)</li>
</ol>
<p>当たり前だが、SCU側がアソシエーションを要求するところから始まる<br />
<div class="table-responsive"><table>
<thead>
<tr>
<th>SCU</th>
<th></th>
<th>SCP</th>
</tr>
</thead>
<tbody>
<tr>
<td>アソシエーション要求</td>
<td>→</td>
<td></td>
</tr>
<tr>
<td></td>
<td>←</td>
<td>アソシエーション要求承諾</td>
</tr>
<tr>
<td>データ送信(続きあるよ)</td>
<td>→</td>
<td></td>
</tr>
<tr>
<td></td>
<td>←</td>
<td>データ受信</td>
</tr>
<tr>
<td>データ送信(ここで終わり)</td>
<td>→</td>
<td></td>
</tr>
<tr>
<td></td>
<td>←</td>
<td>データ受信</td>
</tr>
<tr>
<td>アソシエーション解放要求</td>
<td>→</td>
<td></td>
</tr>
<tr>
<td></td>
<td>←</td>
<td>アソシエーション解放要求承諾</td>
</tr>
</tbody>
</table></div></p>
<p>実際にはアソシエーション張る時にAEタイトルやAbstruct Syntax(SOP Class)、Transfer Syntax(ILE、ELE、JPEGLossyとか)確認する。<br />
データの送信中もC-STOREとかC-FINDとかそれぞれに応じたメッセージを使う。<br />
それはまた別で説明。</p>
<h1 id="DICOMタグの構造"><a href="#DICOM%E3%82%BF%E3%82%B0%E3%81%AE%E6%A7%8B%E9%80%A0">DICOMタグの構造</a></h1>
<p>患者名や検査日時、検査した結果の各種数値などなどはタグという形で保存されている。<br />
バイナリ的に見れば<br />
* TagNo<br />
* VR(Implicitだと省略)<br />
* Length<br />
* Value</p>
<p>という構造になる。</p>
<h2 id="データ構造"><a href="#%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0">データ構造</a></h2>
<p>PS3.5の7.1を見ると色々書いてある。ILE,ELEとかパターン分けがあるが、簡単にだけ書いておくと<br />
* ILE=Implicit VR Little Endian:VRを省略する書き方(たぶん主流)<br />
* ELE=Explicit VR Little Endian:VRを明示的に書き出す書き方(メディア出力時とかはたまにこれの人がいる気がする)</p>
<p>※Little EndianのあたりはDICOM関係ないから他所でどうぞ。ただEBEとかはRETIREしたからあまり考えなくていいかもしれない。</p>
<p>要は<br />
TagNoがあって、VRがあるかないか、長さがあって、値がある<br />
というだけ。<br />
知らないとわからないけど知ってればたいしたことはない。あとのVMとかSQタグとかでまた少し頭使うけど基本はこんな感じ。</p>
<h2 id="TagNo"><a href="#TagNo">TagNo</a></h2>
<p>TagNoの構造はGroupTagと呼ばれるうえ4桁、ElementTagと呼ばれる下4桁の計8桁の16進数で表される。GroupTag、ElementTagに従って(gggg,eeee)という書かれ方をすることもある。<br />
タグには大きく2種類あり、DICOM共通の標準タグ、標準タグで補えない情報がある場合に各団体が発行するプライベートタグ(PrivateTag)がある。</p>
<p>標準タグもだいたいGroupでどんな内容が入っているか決まっていて<br />
<div class="table-responsive"><table>
<thead>
<tr>
<th>GroupTag</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>0008</td>
<td>検査情報</td>
</tr>
<tr>
<td>0010</td>
<td>患者情報</td>
</tr>
<tr>
<td>0018</td>
<td>画像収集情報</td>
</tr>
<tr>
<td>0020</td>
<td>画像付帯情報(たしか0018が多すぎてこっちに広がったと聞いた気がする)</td>
</tr>
<tr>
<td>0028</td>
<td>画像表示情報</td>
</tr>
<tr>
<td>7FE0</td>
<td>画素情報.(7FE0,0010)が画像のバイナリデータ</td>
</tr>
</tbody>
</table></div></p>
<p>※7FE0に関しては0008(Float)とか0009(Double Float)もあるけど使われてるのを知らない。</p>
<h3 id="PrivateTag"><a href="#PrivateTag">PrivateTag</a></h3>
<p>PrivateTagの見分けは簡単でGroupTagが奇数であること。逆に偶数であれば標準タグ。<br />
PrivateTagを発行した場合、必ず発行者を示すPrivateCreatorタグが必要となる。<br />
PrivateCreatorは(gggg,00ee)と決まっており、ElementTagの上位2桁は00と固定である。<br />
また、このPrivateCreatorが保証する範囲は(gggg,ee00-eeFF)までとなる。<br />
具体例を挙げると</p>
<pre><code>(0031,0033)="WATASHIDA"
</code></pre>
<p>が保証するのは</p>
<pre><code>(0031,3300)
(0031,3301)
(0031,3302)
…
(0031,33FF)
</code></pre>
<p>までということ。PrivateCreatorのElement頭2桁が00なのもこれが理由。</p>
<p>当たり前のことだけど独自のPrivateTagを出して、他所で使ってもらいたいならDICOM C/Sにちゃんと書いておくこと。</p>
<h2 id="VR=Value Representation"><a href="#VR%3DValue+Representation">VR=Value Representation</a></h2>
<p>そのタグの値が何で表されるか。<br />
例えばSSならSigned Short、ULならUnsigned Long、STならShort Textといった具合に数値なら型が色々、文字列系なら長さや使用できる文字などの制限が様々、日付や時間、一部タグに特化したVRまで定義されているのでわからないうちはPS3.5の6.2の表を印刷して持っておくといい。</p>
<h2 id="VM=Value Multiplicity"><a href="#VM%3DValue+Multiplicity">VM=Value Multiplicity</a></h2>
<p>そのタグがいくつの値で構成されているか。<br />
例えば患者の向きなどの情報の場合、3軸で表すのでVM=3。<br />
バイナリで見たときにVMを示す領域はないので、<br />
数値のように固定長の場合、VRとLengthから割り出す。SS(2byte)でLengthが6ならVM=6/2=3。<br />
文字列のような可変長の場合は、区切り文字"バックスラッシュ(\)[5CH]"が入るのでそこから割り出す。ImageType(0008,0008)が「ORIGINAL\PRIMARY\HOGEHAGE」の場合、区切り文字が2個なのでVM=3。</p>
<h2 id="SQタグ"><a href="#SQ%E3%82%BF%E3%82%B0">SQタグ</a></h2>
<p>ちょっと特殊なタグでこのタグ自体に値はないが子供を持つことができるタグ<br />
例えばこんな風に</p>
<pre><code>Referenced SOP Sequence(0008,1199)[SQ]
>Referenced SOP Class UID(0008,1150)[UI]
>Referemced SOP Instance UID(0008,1155)[UI]
</code></pre>
<p>※親子関係を表すのに">"を使う</p>
<p>バイナリ的にはまた複雑でPS3.5の7.5.2を参照した方が早い。<br />
おそらくすごいこんがらがるから実際のデータをバイナリエディタで開きながら見たほうがいい。<br />
ポイントは<br />
* SQもVM複数のことがある<br />
* SQの場合、他のタグの値に当たる部分に、さらにItemがあり、他のタグと同様のセットが現れる<br />
* 長さが分からないときに区切りになるタグが存在する<br />
* (FFFE,E000)、(FFFE,E00D)、(FFFE,E0DD)に注意する</p>
<p>このへんを頭に入れながら一つずつ読み解いていくとそのうち理解できるはず。</p>
<h2 id="Type"><a href="#Type">Type</a></h2>
<p>SOPごとに必要なタグ、あったらいいななタグなど違ってくるので、それぞれの場合の必要度を示すものがType、なぜかDICOM C/SではTypeで書かない(VNAPとかで書く)。<br />
* Type1:必ず必要、値も必要。=ALWAYS<br />
* Type2:タグは必ず必要、ただし値はなくてもいい。=VNAP(Value Not Always Present)<br />
* Type3:タグも値もなくてもいい。=ANAP(Attribute Not Always Present)<br />
* Type1C:Conditionを満たす場合Type1として振る舞う。</p>
<hr />
<p>とりあえずここまで。</p>
RedCol
tag:crieit.net,2005:PublicArticle/17679
2021-09-17T18:37:29+09:00
2021-09-17T18:37:29+09:00
https://crieit.net/posts/akapost-dcmtk
DICOM Toolkit(dcmtk) 使い方
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>DICOM Toolkit(dcmtk)の使い方を毎回調べるのが馬鹿らしいのでまとめる。</p>
<p>日本語で教えてくれる優しいところがないので、とりあえず動かすを第一目標に調べた結果を残す。<br />
基本的なオプションのみまとめる。もっと知りたければ頑張ってマニュアル読む。</p>
<p>DICOM的なワードもそのうちまとめる。</p>
<h1 id="Storage SCP(受信)"><a href="#Storage+SCP%28%E5%8F%97%E4%BF%A1%29">Storage SCP(受信)</a></h1>
<p>storescp.exe -v -aet [AEタイトル] [port]</p>
<ul>
<li>-v:詳細を出すだけなのでなくてもいい。</li>
<li>-aet:自身(SCP)のAEタイトル。後に続くportも自身(SCP)のもの。</li>
</ul>
<hr />
<p>例:AEタイトル=TESTSVR、ポート=4006でDICOM受信したい場合<br />
storescp.exe -v -aet TESTSVR 4006</p>
<hr />
<p>実行後は受付待ちに入るので、他の操作がしたいなら別窓開いて作業する。</p>
<h1 id="Storage SCU(送信)"><a href="#Storage+SCU%28%E9%80%81%E4%BF%A1%29">Storage SCU(送信)</a></h1>
<p>storescu.exe -v -aet [送り元AEタイトル] -aec [送り先AEタイトル] [hostname] [port] [DICOM File]</p>
<ul>
<li>-v:詳細を出すだけなのでなくてもいい。</li>
<li>-aet:自身(SCU)のAEタイトル。</li>
<li>-aec:相手(SCP)のAEタイトル。後に続くhostname,portも相手(SCP)のもの。</li>
<li>[DICOM File]:転送したいDICOMファイル。相対パス可。ワイルドカード(*)可。</li>
</ul>
<hr />
<p>例:自身のAEタイトル=TESTSVR1から<br />
相手のAEタイトル=TESTSVR2(ホスト名=SCPSVR、ポート=4006)に<br />
カレント下のdataフォルダの拡張子.dcmのファイルのみDICOM送信したい場合<br />
storescu.exe -v -aet TESTSVR1 -aec TESTSVR2 SCPSVR 4006 .\data*.dcm</p>
<hr />
<h1 id="Modality Worklist(MWM) SCP"><a href="#Modality+Worklist%28MWM%29+SCP">Modality Worklist(MWM) SCP</a></h1>
<p>あらかじめWorklistファイル(.wl)を作っておく必要がある。<br />
毎回データ作るの大変なのでpowersehllで自動生成するスクリプトを書いたが公開するには恥ずかしいレベルなので割愛。</p>
<h2 id="1. データのもとになる.dumpファイルを作る"><a href="#1.+%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%82%82%E3%81%A8%E3%81%AB%E3%81%AA%E3%82%8B.dump%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8B">1. データのもとになる.dumpファイルを作る</a></h2>
<p>[dcmtk置いたパス]\share\dcmtk\wlistdb\OFFISにサンプルがあるのでそれを参考に作る<br />
※1ファイル1件</p>
<pre><code>(0008,0050) SH 00000
(0040,0100) SQ
(fffe,e000) -
(0008,0060) CS MR
(0032,1070) LO BARIUMSULFAT
(fffe,e00d) -
(fffe,e0dd) -
</code></pre>
<p>注意:上記は説明用にだいぶ端折ってるので、必須タグとかは自分で書くこと。</p>
<p>基本は(gggg,eeee) [VR] [Value]の順に一行一タグで書いていく。<br />
SQタグは構造示すタグが挟まるので、上記のようにVRはハイフン、値は無しで書く。</p>
<p>軽く触れておくと<br />
* (fffe,e000) : SQItem開始<br />
* (fffe,e00d) : SQItemデリミタ(SQItemがLength不明の場合)<br />
* (fffe,e0dd) : SQデリミタ(SQ全体がLength不明の場合)<br />
詳細はPS3.5あたりに書いてあるのでそちらを参照のこと。</p>
<h2 id="2.dumpファイルからWorklistファイルを作る"><a href="#2.dump%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89Worklist%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8B">2.dumpファイルからWorklistファイルを作る</a></h2>
<p>dump2dcm [1で作ったdumpファイルのパス] [出力先のパス]</p>
<hr />
<p>例:カレント下のdataフォルダのwklist1.dumpを同じフォルダのwklist1.wlにDICOM変換したい場合<br />
dump2dcm.exe .\data\wklist1.dump .\data\wklist1.wl</p>
<hr />
<p>複数作るだろうからスクリプト書いてぐるぐる回すといい<br />
確か勝手に同名ファイルは作ってくれなかったはず。</p>
<h2 id="3.WorklistファイルをC-FINDを受けるAEタイトル名と同名フォルダに入れる(フォルダ名注意)"><a href="#3.Worklist%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92C-FIND%E3%82%92%E5%8F%97%E3%81%91%E3%82%8BAE%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB%E5%90%8D%E3%81%A8%E5%90%8C%E5%90%8D%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AB%E5%85%A5%E3%82%8C%E3%82%8B%28%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E5%90%8D%E6%B3%A8%E6%84%8F%29">3.WorklistファイルをC-FINDを受けるAEタイトル名と同名フォルダに入れる(フォルダ名注意)</a></h2>
<p>SCUからC-FINDかけてくるAEタイトルのフォルダを作って、その中に入れておく必要あり。<br />
次の手順と合わせてよく忘れるので注意。<br />
また、"lockfile"もAEタイトルフォルダの中に作っておく(wlmcspfs流すときに必要)</p>
<hr />
<p>例:問い合わせを受けるAEタイトル=MWMTEST、カレント下のdataフォルダにWorklistファイル(wklist1.wl)を置く場合<br />
.\data\MWMTEST\wklist1.wl<br />
.\data\MWMTEST\lockfile</p>
<hr />
<h2 id="4.MWM受付待ち状態にする(パス指定注意)"><a href="#4.MWM%E5%8F%97%E4%BB%98%E5%BE%85%E3%81%A1%E7%8A%B6%E6%85%8B%E3%81%AB%E3%81%99%E3%82%8B%28%E3%83%91%E3%82%B9%E6%8C%87%E5%AE%9A%E6%B3%A8%E6%84%8F%29">4.MWM受付待ち状態にする(パス指定注意)</a></h2>
<p>wlmscpfs.exe -v -csk -dfp [3のAETITLEフォルダの親のパス] [port]</p>
<ul>
<li>-v ; 詳細表示</li>
<li>-csk : キャラクタセット(文字セット)を維持。指定もできるけど基本的には維持で取っておけばあんまり困らない。</li>
<li>-dfp : データファイルパス。AEタイトルフォルダの一個上を指定。このパスの下にあるAEタイトルを探すことになるらしい。一番はまったところ。注意。</li>
</ul>
<hr />
<p>例:カレント下のdataフォルダにAEタイトルフォルダ作ってWorklistファイル(wklist1.wl)を置いた場合<br />
wlmscpfs.exe -v -csk -dfp .\data 4006</p>
<hr />
<p>実行後は受付待ちに入るので、他の操作がしたいなら別窓開いて作業する。</p>
<h2 id="番外:日本語の取り扱い"><a href="#%E7%95%AA%E5%A4%96%EF%BC%9A%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84">番外:日本語の取り扱い</a></h2>
<p>Specific Character Set(0008,0005)に"\ISO 2022 IR87"セットして、<br />
バイナリエディタ使って、日本語の前後にエスケープ(iB 24 42 日本語 1B 28 42)入れて、<br />
Lengthも合わせてみたけどうまくいかなかった。<br />
一時調査中断中。</p>
<p>一方でUTF-8でならうまくいったので、こだわりがなければこっちで。<br />
1.Specific Character Set(0008,0005)に"ISO IR192"セット<br />
2.dumpに日本語を入力してUTF-8で保存<br />
3.メモ帳編集の場合BOMが入ったので先頭3バイト削除<br />
4.dump2dcmでwlファイル作る</p>
<h1 id="Query/Retreive(Q/R) SCP"><a href="#Query%2FRetreive%28Q%2FR%29+SCP">Query/Retreive(Q/R) SCP</a></h1>
<h2 id="1.DICOMファイルのIndex作成"><a href="#1.DICOM%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AEIndex%E4%BD%9C%E6%88%90">1.DICOMファイルのIndex作成</a></h2>
<p>Q/RさせるDICOMファイル群のIndexファイルを作る(これを使ってQueryを返すらしい。)</p>
<p>dcmqridx.exe -v [index出力先フォルダ] [対象のDICOMファイル]</p>
<hr />
<p>例:カレント下のdataフォルダにDICOMファイルがあり、同じフォルダにIndexファイルを吐き出す場合<br />
dcmqridx.exe -v .\data .\data*.dcm</p>
<hr />
<h2 id="2.設定ファイルを作る"><a href="#2.%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8B">2.設定ファイルを作る</a></h2>
<p>[dcmtk置いたパス]\etc\dcmtk\dcmqrscp.cfgにサンプルがあるのでコピーして使う</p>
<h3 id="2-1.Q/R SCU(問い合わせ元)の情報を設定する"><a href="#2-1.Q%2FR+SCU%28%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B%E5%85%83%29%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B">2-1.Q/R SCU(問い合わせ元)の情報を設定する</a></h3>
<p>Host TableのBEGINからENDの間に<br />
[設定名] = ([AEタイトル], [HostName], [Port])<br />
の形で書く。</p>
<hr />
<p>例:AEタイトル=TESTSVR1、HostName=SCUTEST、Port=4006をqrtestの名前で設定する場合<br />
HostTable BEGIN<br />
qrtest = (TESTSVR1, SCUTEST, 4006)<br />
HostTable END</p>
<hr />
<p>なお、複数の設定を一個の設定にまとめたりもできるとのこと<br />
[設定名1] = ([AEタイトル], [HostName], [Port])<br />
[設定名2] = ([AEタイトル], [HostName], [Port])<br />
[設定名ALL] = [設定名1], [設定名2]</p>
<hr />
<p>例:AEタイトル=TESTSVR1、HostName=SCUTEST1、Port=4006をqrtest1、<br />
AEタイトル=TESTSVR2、HostName=SCUTEST2、Port=4006をqrtest2、<br />
上記二つをqrtestallまとめる場合<br />
HostTable BEGIN<br />
qrtest1 = (TESTSVR1, SCUTEST1, 4006)<br />
qrtest2 = (TESTSVR2, SCUTEST2, 4006)<br />
qrtestall = qrtest1, qrtest2<br />
HostTable END</p>
<hr />
<h3 id="2-2.Q/R SCP(問い合わせ先)の情報を設定する"><a href="#2-2.Q%2FR+SCP%28%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B%E5%85%88%29%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B">2-2.Q/R SCP(問い合わせ先)の情報を設定する</a></h3>
<p>AE TableのBEGINからENDの間に<br />
[AEタイトル] [Q/RさせるDICOMファイル置き場] [Read/Write] [(最大検査数, 最大検査Byte)] [対応するHostTable設定名]<br />
の形で書く。</p>
<p>DICOMファイル置き場はここで相対書くとどこからになるか不明。試したことはない。<br />
やってみたくなったら試して結果を追記する。</p>
<p>Read/WriteはQRで書いてどうするんだろうと思うけどわからないときはRW<br />
最大検査数、バイトに関してはある程度で絞っておかないと用意した検査数によっては泣きたくなるので適宜。</p>
<hr />
<p>例:AEタイトル=QRSCPAE、ファイル置き場=H:DICOM¥QRSCP¥QRTEST、最大検査を200件、1024MBとし、qrtest1に設定した相手のみ有効とする場合<br />
AETable BEGIN<br />
QRSCPAE H:DICOM¥QRSCP¥QRTEST RW (200,1024mb) qrtest1<br />
AETable END</p>
<hr />
<h2 id="3.Query待ち状態にする"><a href="#3.Query%E5%BE%85%E3%81%A1%E7%8A%B6%E6%85%8B%E3%81%AB%E3%81%99%E3%82%8B">3.Query待ち状態にする</a></h2>
<p>dcmqrscp -v -c [設定ファイルのパス] [Port]<br />
* -v : 詳細表示<br />
* -c : 設定ファイルのパス指定</p>
<hr />
<p>例:カレント下のetcに2の設定ファイルがあり、Port=4006で受け付ける場合<br />
dcmqrscp -v -c .\etc\dcmqrscp.cfg 4006</p>
<hr />
<p>実行後は受付待ちに入るので、他の操作がしたいなら別窓開いて作業する。</p>
<h1 id="Modality Performed Procedure Step(MPPS)"><a href="#Modality+Performed+Procedure+Step%28MPPS%29">Modality Performed Procedure Step(MPPS)</a></h1>
<p>ppsscpfsなるものがあるらしいが、見当たらない。<br />
誰か教えてほしい。</p>
RedCol