0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windowsで常駐プロセスをコンソールなしで自動起動:VBS + タスクスケジューラをOllamaで実機検証

0
Posted at

はじめに

Ollamaの serve や自作の常駐スクリプトなど、「ログオン時に自動で立ち上げておきたいが、黒いコンソールウィンドウは出したくない」ものは多い。Windowsのタスクスケジューラはログオン時に実行できるが、コンソールアプリを直接登録するとウィンドウが表示される。そこで、VBScriptの WshShell.Run をワンクッション挟んで非表示で起動する。

本記事は、この構成を筆者のWindows実機で検証した結果をまとめたもの。検証のお題はOllamaの ollama serve。

環境

  • Windows 11(ビルド 10.0.26200)
  • PowerShell 5.1
  • Ollama 0.40.4(公式インストーラ版。%LOCALAPPDATA%\Programs\Ollama\ollama.exe)

やったこと

1. 非表示で起動するVBSを作る

launch_hidden.vbs:

Set sh = CreateObject("WScript.Shell")
ollama = sh.ExpandEnvironmentStrings("%LOCALAPPDATA%\Programs\Ollama\ollama.exe")
sh.Run """" & ollama & """ serve", 0, False

ポイントは Run(コマンド, 0, False) の第2引数 0(ウィンドウスタイル: 非表示)と第3引数 False(プロセスの終了を待たない)。

Run はコマンド文字列中の環境変数を展開しないため、%LOCALAPPDATA% などのパスは ExpandEnvironmentStrings で先に展開しておく。PowerShellスクリプトを経由したい場合も同じ要領になる。

sh.Run "powershell.exe -NoProfile -ExecutionPolicy Bypass -File """ & scriptPath & """", 0, False

2. 本当に「非表示」か確認する

目視だけでは心もとないので、起動されたプロセス自身に申告させる。

$me = Get-Process -Id $PID
"handle=$($me.MainWindowHandle) title='$($me.MainWindowTitle)'"

VBS経由で起動したところ、実際の出力はこうだった。

handle=0 title=''

MainWindowHandle が 0、つまりウィンドウを持たない状態で動作していることが確認できた。

3. タスクスケジューラに登録する

まずは影響の少ない「1回だけ」のタスクで動作確認する。この時点では管理者権限は不要。

$vbs = "$env:USERPROFILE\launch_hidden.vbs"
$tr = "wscript.exe `"$vbs`""

schtasks /create /tn "HiddenLauncher" /tr "$tr" /sc once /st 23:59 /f
schtasks /run /tn "HiddenLauncher"
schtasks /delete /tn "HiddenLauncher" /f

実測結果:

  • 作成: SUCCESS: The scheduled task "HiddenLauncher" has successfully been created.
  • 実行: SUCCESS。起動されたプロセスは MainWindowHandle=0 のまま(非表示)
  • 削除: SUCCESS

本番は「ログオン時」に変える。

schtasks /create /tn "HiddenLauncher" /tr "$tr" /sc onlogon /f

ただしこれは、管理者権限でないと作成できない(実測)。

ERROR: Access is denied.

本番登録だけは管理者として実行したPowerShellから行い、動作確認は非管理者で /sc once を使う、と切り分けるとやりやすい。

4. 二重起動を防ぐ

常駐プロセスは「すでに起動していないか」を確認してから立ち上げたい。Ollamaのサーバーならポートを確認する。

$listening = Get-NetTCPConnection -LocalPort 11434 -State Listen -ErrorAction SilentlyContinue
if ($listening) { exit }

検証中、Windowsでは ollama serve の二重起動がエラーにならないことに気づいた。既存のOllamaサーバーがLISTEN中の状態で、VBSからもう1つ serve を起動すると、後から起動した方が別アドレスでLISTENし、両方のプロセスがLISTEN状態のまま共存してしまった。エラーにはならないため、ポートを確認しないと「いつの間にか2つ動いている」状態になり得る。

ハマった点

  1. /sc onlogon は管理者権限が必須。非管理者で実行すると ERROR: Access is denied. になる。/sc once は非管理者でも作成できるので、テストと本番登録で権限を分けるとよい。
  2. VBSの Run は環境変数を展開しない。%LOCALAPPDATA% などをそのまま書いても展開されないため、ExpandEnvironmentStrings で事前に展開する。
  3. Windowsは同一ポートの二重LISTENを許す場合がある。バインドエラーで気づけないので、起動前に Get-NetTCPConnection でLISTENの有無を確認する。
  4. 非表示かどうかの判定は MainWindowHandle を見るのが手軽。タスクスケジューラ経由で起動したプロセスでも 0 のままだった。

まとめ

  • VBSの Run(コマンド, 0, False) をワンクッション挟むことで、タスクスケジューラからコンソールを出さずに常駐プロセスを起動できる。
  • 動作テストは非管理者で /sc once、本番は管理者権限で /sc onlogon。
  • 起動前のポート確認(二重起動対策)を忘れない。

なお、Ollama公式アプリ自体がログオン時に常駐してサーバーを起動する構成のため、Ollamaについては公式アプリに任せるのが基本で、この仕組みは「自作の常駐ツールをコンソールなしで立ち上げたいとき」に効く。

関連する本

この常駐起動の仕組みを、ローカルLLMの自動実行まで含めて一冊にまとめました。第1章・第2章は無料で読めます。

Windowsで動かすローカルLLM自動化:Ollama実測ガイド

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?