Tauri で OS 起動時の自動起動を適用する

# はじめに

やはりアプリに OS 起動時の自動起動を付与するといった発想はよくあるというもの。
ということで、Tauri もその機構をプラグインとして提供している。

https://github.com/tauri-apps/tauri-plugin-autostart

こちらは関連した GitHub Issue。

https://github.com/tauri-apps/tauri/issues/2589


### 検証環境

* Windows 11 Pro 23H2
* Tauri 1.5.3
* Rust 1.74.1

### サンプル実装

https://github.com/takavfx/learn_tauri_examples/tree/2024.3.24_1/autostart

# 設定方法

## インストール

```toml:Cargo.toml
[dependencies]
tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
```

フロントエンド側でのアクセスも必要な場合は別途インストールする。

```powershell
npm install https://github.com/tauri-apps/tauri-plugin-autostart#v1
```

## 実装方法

### バックエンド

```rust
use tauri_plugin_autostart::MacosLauncher;

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_autostart::init(
            MacosLauncher::LaunchAgent,
            Some(vec!["--flag1", "--flag2"]), // 特に指定なしであれば Some(vec![]) を渡す。
        ))
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
```

起動時に何らかの引数を渡したい場合は `Some(vec!["--flag1", "--flag2"]` として事前設定しておく。
なぜこういう仕組みかは、例えば Windows の場合はレジストリ登録によって自動起動を実現しているので、引数の設定の余地がないためらしい。（後述の「中身をのぞいてみる」を参照


### フロントエンド

```typescript
import { enable, isEnabled, disable } from "tauri-plugin-autostart-api";
    
await enable();
    
console.log(`registered for autostart? ${await isEnabled()}`);
    
disable();
```

# サンプル実装

試しに実装してみる。
main.rs は上記サンプルそのままコピペで OK。
なので、フロントエンドの感じだけ。

```svelte:+page.svelte
<script lang="ts">
	import { Label, Toggle } from 'flowbite-svelte';
	import { enable, disable, isEnabled } from 'tauri-plugin-autostart-api';

	let autoStart = false;

    // isEnable は Promise で帰ってくるので、.then で対応
	$: isEnabled().then((isEnabled) => (autoStart = isEnabled));

    // Toggle (checkbox の Flowbite 版) の切り替え時のコールバック関数
	async function onAutostartChanged() {
		autoStart = !autoStart;
		autoStart ? enable() : disable();
	}
</script>

<div class="flex flex-col">
	<ul class="m-3 divide-y-2">
		<li class="flex justify-between py-3">
			<div class="flex flex-col">
				<Label class="font-semibold">Autostart</Label>
				<Label class="text-gray-400 ">
                    App autostart when operating system started.
                </Label>
			</div>
			<Toggle checked={autoStart} on:change={onAutostartChanged} />
		</li>
	</ul>
</div>

```

次の様にトグルすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/cc9bcd7c-a406-5590-eeb1-49c41a5db6a6.png)

レジストリエディタで見たときに、`コンピューター\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run` にて登録されているのが分かる。
もう一回トグルして `false` 状態にすると、レジストリエディタ上からも消えているのが確認できる。
(レジストリエディタ上でのリアルタイム変更は確認できないので、一度他のデイレク取りに表示を切り替えてから戻ると反映されているのが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/7e575d77-de8f-0cca-365c-535f37eb4d54.png)

# 中身をのぞいてみる

どういう仕組みなの？ってのが気になったので、ソースコードを覗いてみたメモ。

https://github.com/tauri-apps/tauri-plugin-autostart/blob/v1/src/lib.rs

依存関係として、 [auto-launch](https://crates.io/crates/auto-launch) というクレートを使用している。
これ自体は、**Windows, macOS, Linux に対応している**様子。

自動起動が有効か無効かなどのステート管理は `AutoLaunchManager` 構造体として管理。

https://github.com/tauri-apps/tauri-plugin-autostart/blob/v1/src/lib.rs#L42-L65

起動した際のアプリの実行位置を OS ごとに設定している様子。

https://github.com/tauri-apps/tauri-plugin-autostart/blob/v1/src/lib.rs#L111-L140

では、 [auto-luanch](https://crates.io/crates/auto-launch) はどうなっているかを見てみる。

https://github.com/zzzgydi/auto-launch/tree/main/src

Linux / macOS / Windows でそれぞれ起動が切り替えられるようにコンフィグが設定してある。

https://github.com/zzzgydi/auto-launch/blob/main/src/lib.rs#L317-L327

例えば Windows の場合は、レジストリアクセスによってスタートアップ時の起動を制御するように仕込まれている様子。
なのでアンインストール時のレジストリクリアとかも実装した方がいいかも。

https://github.com/zzzgydi/auto-launch/blob/main/src/windows.rs#L42-L44


# おわりに

Tauri での OS 起動時の自動起動実装もあっさり行けてしまった。

Tauri はプラグインとしてこういった機能もどんどん拡張されていっている様子。
なんだか自分でもいくつかプラグインを書いていきたい気分。
（v2 でプラグインの書き方も変わるので、それから考えてみようかな。