@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/single-instance-mutex-guide/#article>
    schema:about <https://comcomponent.com/knowledge/named-mutex/>, <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    schema:mentions <https://comcomponent.com/knowledge/kernel-object-namespace/>, <https://comcomponent.com/knowledge/abandoned-mutex-exception/>, <https://comcomponent.com/knowledge/mutex-name-squatting/>, <https://comcomponent.com/knowledge/mutex-acl/>, <https://comcomponent.com/knowledge/setforegroundwindow/>, <https://comcomponent.com/knowledge/allowsetforegroundwindow/>, <https://comcomponent.com/knowledge/named-pipe/>, <https://comcomponent.com/knowledge/getnamedpipeserverprocessid/>, <https://comcomponent.com/knowledge/currentuseronly-pipeoption/>, <https://comcomponent.com/knowledge/admin-rights/>, <https://comcomponent.com/knowledge/winobj/>, <https://comcomponent.com/knowledge/task-scheduler/>, <https://comcomponent.com/knowledge/dotnet/>, <https://comcomponent.com/knowledge/integrity-level/> .

<https://comcomponent.com/knowledge/named-mutex/> a skos:Concept ;
    skos:prefLabel "名前付きMutex"@ja ;
    skos:definition "名前を指定して作成し、その名前を知っている他のプロセスからも同じインスタンスを参照できる、相互排他用のWindowsカーネルオブジェクト。"@ja ;
    skos:altLabel "Named Mutex" ;
    skos:altLabel "名前付きミューテックス"@ja ;
    ks:uses <https://comcomponent.com/knowledge/kernel-object-namespace/> ;
    ks:verifiedBy <https://comcomponent.com/knowledge/winobj/> ;
    ks:configuredBy <https://comcomponent.com/knowledge/mutex-acl/> .

<https://comcomponent.com/knowledge/single-instance-enforcement/> a skos:Concept ;
    skos:prefLabel "多重起動防止(シングルインスタンス化)"@ja ;
    skos:definition "同一アプリケーションの起動を、セッション・ユーザー・マシンなど選んだ単位で1つに制限する設計。"@ja ;
    skos:altLabel "Single Instance" ;
    skos:altLabel "多重起動対策"@ja .

<https://comcomponent.com/knowledge/kernel-object-namespace/> a skos:Concept ;
    skos:prefLabel "カーネルオブジェクト名前空間(Global\\/Local\\)"@ja ;
    skos:definition "セッションごとに独立したLocal名前空間と、システム全体で共有されるGlobal名前空間で構成される、Windowsの名前付きカーネルオブジェクトの名前解決の仕組み。"@ja ;
    skos:altLabel "Kernel Object Namespaces" ;
    skos:altLabel "セッション名前空間"@ja ;
    skos:broader <https://comcomponent.com/knowledge/object-manager/> .

<https://comcomponent.com/knowledge/mutex-acl/> a skos:Concept ;
    skos:prefLabel "MutexSecurity/ACLによるMutex保護"@ja ;
    skos:definition "名前付きMutexの作成時にACLを明示し、自分が先に作成できた場合に他ユーザーによる乗っ取り・不正保持を防ぐ設定。"@ja ;
    skos:altLabel "MutexAcl.Create" ;
    skos:altLabel "MutexSecurity" ;
    ks:requires <https://comcomponent.com/knowledge/dotnet/> .

<https://comcomponent.com/knowledge/admin-rights/> a skos:Concept ;
    skos:prefLabel "管理者権限"@ja ;
    skos:definition "コンピューター全体の設定を変更できる権限。"@ja ;
    skos:altLabel "昇格"@ja .

<https://comcomponent.com/knowledge/mutex-name-squatting/> a skos:Concept ;
    skos:prefLabel "Mutexの名前占有(スクワッティング)"@ja ;
    skos:definition "悪意あるユーザーが先回りして同じ名前のMutexを作成し、アプリの多重起動防止の判定を妨害する手口。"@ja ;
    skos:altLabel "名前スクワッティング"@ja .

<https://comcomponent.com/knowledge/dotnet/> a skos:Concept ;
    skos:prefLabel ".NET(Core以降)"@ja ;
    skos:definition ".NET Frameworkの後継となる、クロスプラットフォーム対応の.NETランタイム(.NET 5以降)。"@ja ;
    skos:altLabel ".NET Core" ;
    skos:altLabel "モダンな.NET"@ja .

<https://comcomponent.com/knowledge/currentuseronly-pipeoption/> a skos:Concept ;
    skos:prefLabel "PipeOptions.CurrentUserOnly"@ja ;
    skos:definition "名前付きパイプへの接続を、現在のユーザー(かつ同じ昇格レベル)に限定する.NETのアクセス制御オプション。"@ja ;
    skos:altLabel "CurrentUserOnly" ;
    ks:requires <https://comcomponent.com/knowledge/integrity-level/> .

<https://comcomponent.com/knowledge/integrity-level/> a skos:Concept ;
    skos:prefLabel "整合性レベル"@ja ;
    skos:definition "プロセスがどのトークンで動作しているかをlow/medium/high/systemの段階で表し、保護領域への書き込み可否を左右するWindowsのアクセス制御の仕組みである。"@ja ;
    skos:altLabel "Mandatory Integrity Control" ;
    skos:altLabel "medium/high integrity" ;
    skos:broader <https://comcomponent.com/knowledge/uac/> .

<https://comcomponent.com/knowledge/named-pipe/> a skos:Concept ;
    skos:prefLabel "名前付きパイプ"@ja ;
    skos:definition "Windowsのプロセス間通信手段のひとつ。リモートからの利用はアプリ自身のポートではなくSMB(TCP 445)を経由する。"@ja ;
    ks:verifiedBy <https://comcomponent.com/knowledge/getnamedpipeserverprocessid/> .

<https://comcomponent.com/knowledge/getnamedpipeserverprocessid/> a skos:Concept ;
    skos:prefLabel "GetNamedPipeServerProcessId"@ja ;
    skos:definition "接続済みの名前付きパイプのクライアント側ハンドルから、サーバー側プロセスのプロセスIDを取得するWin32 API。"@ja ;
    ks:requires <https://comcomponent.com/knowledge/named-pipe/> .

<https://comcomponent.com/knowledge/allowsetforegroundwindow/> a skos:Concept ;
    skos:prefLabel "AllowSetForegroundWindow"@ja ;
    skos:definition "フォアグラウンドウィンドウを設定できる権限を、プロセスIDで指定した相手プロセスへ譲渡するWin32 API。"@ja .

<https://comcomponent.com/knowledge/setforegroundwindow/> a skos:Concept ;
    skos:prefLabel "SetForegroundWindow"@ja ;
    skos:definition "指定したウィンドウをフォアグラウンドに設定するWin32 API。呼び出し元プロセスが定められた条件を満たさない限り、実際には前面化せずタスクバーボタンの点滅に留まる。"@ja .

<https://comcomponent.com/knowledge/task-scheduler/> a skos:Concept ;
    skos:prefLabel "タスクスケジューラの無人実行"@ja ;
    skos:definition "指定したアカウントで、スケジュールやログオンなどのトリガーに従いプログラムを実行するWindowsの仕組み。ログオン種別(対話トークン・パスワード保存・S4Uなど)の設定によっては、ユーザーがログオンしていなくても実行できる。"@ja .

<https://comcomponent.com/knowledge/winobj/> a skos:Concept ;
    skos:prefLabel "WinObj"@ja ;
    skos:definition "オブジェクトマネージャーの名前空間をツリー表示で閲覧できるSysinternalsのツール。デバイスオブジェクトの実名やシンボリックリンクを確認できる。"@ja ;
    skos:altLabel "WinObj (Sysinternals)" .

<https://comcomponent.com/knowledge/abandoned-mutex-exception/> a skos:Concept ;
    skos:prefLabel "AbandonedMutexException"@ja ;
    skos:definition "Mutexを所有していたスレッドがReleaseMutexを呼ばずに終了した後、次にそのMutexを取得したスレッドへ送出される、待機自体は成功していることを示す例外。"@ja .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-mutex/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/kernel-object-namespace/> ;
    schema:description "名前付きMutexはプレフィックスを指定しない場合は既定でLocal(セッション限定)の名前空間に作られ、Globalを付けたときだけ全セッション共通の名前空間に作られる。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/termserv/kernel-object-namespaces> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/named-mutex/> ;
    schema:description "この記事が採用する検出方式では、同名Mutexの新規作成に成功したか(createdNew)を判定条件として名前付きMutexを利用する(ファイルロックやTCPポート占有など他の実現手段もある)。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.threading.mutex.-ctor> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/kernel-object-namespace/> ;
    schema:description "セッションをまたいで1つのインスタンスに絞りたい場合は、Mutexの名前空間をGlobalに切り替えることを前提とする。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.threading.mutex> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/mutex-acl/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/admin-rights/> ;
    schema:description "ACLを明示したMutexは、作成時と異なる昇格レベル(整合性レベル)のプロセスからの生成・オープンでは両立せず、UnauthorizedAccessExceptionになることがある。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/secauthz/mandatory-integrity-control> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/mutex-acl/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/mutex-name-squatting/> ;
    schema:description "自分が先に作成できた場合に限り、ACLの明示によって他ユーザーによる乗っ取り・不正保持を防げる(先に占有されること自体は防げない)。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/synchapi/nf-synchapi-createmutexw> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/mutex-acl/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/dotnet/> ;
    schema:description "MutexSecurity/MutexAcl.CreateはNuGetパッケージSystem.Threading.AccessControlが提供する型で、.NET(Core以降)でも利用できる。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.threading.mutexacl.create> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/currentuseronly-pipeoption/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/integrity-level/> ;
    schema:description "CurrentUserOnlyは接続元のユーザーアカウントに加えて、サーバーと同じ整合性レベル(昇格レベル)であることまで一致を要求する(双方が非昇格でも一致していれば通る)。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.io.pipes.pipeoptions> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-pipe/> ;
    rdf:predicate ks:configuredBy ;
    rdf:object <https://comcomponent.com/knowledge/currentuseronly-pipeoption/> ;
    schema:description ".NETのNamedPipeServerStreamを使う実装では、名前付きパイプへの接続認可はCurrentUserOnlyで現在のユーザー(かつ同じ昇格レベル)に絞り込める。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.io.pipes.pipeoptions> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/named-pipe/> ;
    schema:description "この記事の設計では、多重起動検出後の通知(起動引数の転送やアクティブ化要求)には名前付きパイプを使う(IPC手段の比較は別記事に譲る)。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/ipc/named-pipes> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-pipe/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/getnamedpipeserverprocessid/> ;
    schema:description "接続済みの名前付きパイプのサーバー側プロセスIDは、GetNamedPipeServerProcessIdで確認できる。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-getnamedpipeserverprocessid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/getnamedpipeserverprocessid/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/named-pipe/> ;
    schema:description "GetNamedPipeServerProcessIdは、接続済みの名前付きパイプのクライアント側ハンドルを引数に取る。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-getnamedpipeserverprocessid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/allowsetforegroundwindow/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/getnamedpipeserverprocessid/> ;
    schema:description "既存インスタンスへフォアグラウンド設定権限を譲渡する宛先のプロセスIDは、接続済みパイプからGetNamedPipeServerProcessIdで取得する設計が定石とされる。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-allowsetforegroundwindow> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/setforegroundwindow/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/allowsetforegroundwindow/> ;
    schema:description "呼び出し元プロセスが定められた条件を満たさない場合、既存インスタンス側のSetForegroundWindowを成功させるには、2つ目のプロセスがAllowSetForegroundWindowで権限を委譲する必要がある。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-setforegroundwindow> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/setforegroundwindow/> ;
    schema:description "この記事の設計では、多重起動を検出した後は、既存インスタンスのウィンドウを前面に出すためSetForegroundWindowを使う。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-setforegroundwindow> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/single-instance-enforcement/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/allowsetforegroundwindow/> ;
    schema:description "この記事の設計では、既存インスタンスの前面化を成功させるため、AllowSetForegroundWindowによる権限委譲を設計に組み込む。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-allowsetforegroundwindow> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/task-scheduler/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/allowsetforegroundwindow/> ;
    schema:description "タスクスケジューラ経由で起動したプロセスは直近の入力イベントを受け取っておらずフォアグラウンド設定権限を持たないため、AllowSetForegroundWindowによる委譲を試みても既存インスタンスの前面化に失敗することがある。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-setforegroundwindow> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-mutex/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/winobj/> ;
    schema:description "作成したMutexが実際にどの名前で存在しているかは、WinObjでオブジェクトマネージャーの名前空間を開いて確認できる。"@ja ;
    ks:evidence <https://learn.microsoft.com/sysinternals/downloads/winobj> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-mutex/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/abandoned-mutex-exception/> ;
    schema:description "Mutexを所有していたスレッドがReleaseMutexを呼ばずに終了すると、次にそのMutexを取得したスレッドにAbandonedMutexExceptionが送出される。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.threading.abandonedmutexexception> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/named-mutex/> ;
    rdf:predicate ks:configuredBy ;
    rdf:object <https://comcomponent.com/knowledge/mutex-acl/> ;
    schema:description "名前付きMutexは、MutexSecurity(MutexAcl.Create)でACLを明示して構成できる。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.threading.mutexacl.create> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .
