実行中の子プロセスを強制終了する

Recipe ID: shell-008

実行中の子プロセスを強制終了する方法を解説します。
spawn() で生成された Child オブジェクトの kill() メソッドを使用します。

前提条件

プラグインのインストールが必要です。

npm run tauri add shell

Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
  "permissions": [
    ...,
    "shell:allow-open",
    "shell:allow-kill",
    {
      "identifier": "shell:allow-execute",
      "allow": [
        {
          "name": "ping",
          "cmd": "ping",
          "args": true
        }
      ]
    },
    {
      "identifier": "shell:allow-spawn",
      "allow": [
        {
          "name": "ping",
          "cmd": "ping",
          "args": true
        }
      ]
    }
  ]
}

1. フロントエンドから作成する (TypeScript)

Child.kill() を呼び出すと、OS に応じた終了シグナル(SIGTERM/SIGKILL 相当)が送信され、プロセスが停止します。

import { Command, Child } from '@tauri-apps/plugin-shell';

let childProcess: Child | null = null;

async function startProcess() {
  // 長く実行させるため、回数を多めに設定 (-c: count)
  const args = ['google.com', '-c', '100'];

  const cmd = Command.create('ping', args);
  childProcess = await cmd.spawn();
  console.log(`Process started: ${childProcess.pid}`);
}

async function stopProcess() {
  if (childProcess) {
    try {
      await childProcess.kill();
      console.log('Process killed successfully');
      childProcess = null;
    } catch (e) {
      console.error('Failed to kill process:', e);
    }
  } else {
    console.log('No process running');
  }
}

2. バックエンドから作成する (Rust)

shell-007 のように State で管理されている Child プロセスを取り出し、.kill() を呼び出します。

use std::process::Child;
use std::sync::Mutex;
use tauri::State;

struct ProcessState(Mutex<Option<Child>>);

#[tauri::command]
fn stop_server(state: State<'_, ProcessState>) -> Result<String, String> {
    let mut lock = state.0.lock().unwrap();
    
    if let Some(mut child) = lock.take() {
        child.kill().map_err(|e| e.to_string())?;
        Ok("Process killed".to_string())
    } else {
        Err("No process running".to_string())
    }
}