8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シェルスクリプト&PowerShellAdvent Calendar 2023

Day 19

なぜstartコマンドはブラウザ名だけでブラウザを開けるのか

Last updated at Posted at 2023-12-18

はじめに

皆さんはこのコマンドを見たことがありますか?

start chrome "https://qiita.com/"

もし初めて見たという方はコマンドプロンプト(PowerShellはNG)で実行してみてください。Chromeが起動してQiitaのページが表示されるはずです。
※Chromeをインストールしてない場合は代わりに msedgefirefox を指定してみてください

さて、このコマンドを見て不思議に思いませんか?

なぜ C:\Program Files (x86)\Google\Chrome\Application\chrome.exe のようにフルパスを指定していないのにブラウザが起動するのか?

この記事ではその理由について解説してみます。

startコマンド

startコマンドとは

Microsoftのドキュメントによると、startコマンドは指定したプログラムまたはコマンドを実行するコマンドで、Windowsのコマンドプロンプトの組み込みコマンドのようです。

例えば

start notepad

を実行するとメモ帳を起動できますし、

例えば

start "現在日付" echo %date% %time%

を実行するとウィンドウ名が "現在日付" の新しいターミナルを開いて現在日付を表示させられます。

ちなみに、組み込みコマンドだからなのか、PowerShellからは直接実行できないです。
※PowerShellの startStart-Process コマンドレットのエイリアス

Get-Command start
# CommandType    Name                         Version    Source
# -----------    ----                         -------    ------
# Alias          start -> Start-Process

実行ファイルの検索

上記の例だとメモ帳を notepad だけで指定していますが、メモ帳の実体は C:\WINDOWS\system32\notepad.exe です。

ではなぜ前述のChromeの例や上記のメモ帳の例ではファイル名だけでアプリを起動できるのでしょうか?

まず拡張子の省略について、Microsoftのドキュメントに以下のような記載があります。

実行するコマンドで最初に使用されているトークンが、コマンドでも、拡張子を持つ既存のファイルへのファイル パスでもない場合は、Cmd.exe により、PATHEXT 環境変数の値を使用して、検索する拡張子とその順序が決定されます。 PATHEXT 変数の既定値は、.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC です。

つまり拡張子が省略された場合は .com.exe とみなして検索されるみたいです。

次にディレクトリの省略について、Stackoverflowにまさにちょうど同じ内容の質問がありました。

ざっくり要約すると

Q. firefox.exeをどこでもstartで実行できるのはなんで?他の実行ファイルは親ディレクトリに移動しないと実行できないのに。

A. それは "App Paths" に追加されてるからだよ。これは環境変数を書き換えるよりも優れた方法なんだ。

という内容です。

ここで言及されている "App Paths" というのはレジストリ値で、以下に詳細が書かれています。

使い方としては "App Paths" 配下に実行ファイルのファイル名をサブキーとしたエントリを作成して、既定値に実行ファイルのフルパスを、Pathに親ディレクトリを設定するようです。

\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe

Property
  (default) = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
  Path      = C:\Program Files (x86)\Google\Chrome\Application

気になる方は以下のコマンドをPowerShellで実行してみてください。現時点でどんな値が設定されているかを調べることができます。

App Pathsの一覧確認
@("HKCU", "HKLM") | % {
  $rootKey = $_
  Write-Host "${rootKey}"
  $appPaths = (Get-Item "${rootKey}:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths")
  $appPaths.GetSubKeyNames() | % {
    $subKeyName = $_
    Write-Host "  ${subKeyName}"
    $entry = (Get-Item "${rootKey}:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\${subKeyName}")
    $entry.GetValueNames() | % {
      $valueName = $_
      $value = $entry.GetValue($valueName)
      if ($valueName -eq "") {
        $key = "(default)"
      } else {
        $key = $valueName
      }
      Write-Host "    ${key} : ${value}"
    }
  }
}
出力結果のサンプル
HKCU
  OneDriveFileLauncher.exe
    SkipCloudDownload : 1
  WindowsPackageManagerServer.exe
    (default) : C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.21.3421.0_x64__8wekyb3d8bbwe\WindowsPackageManagerServer.exe
    Path : C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.21.3421.0_x64__8wekyb3d8bbwe
  winget.exe
    (default) : C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.21.3421.0_x64__8wekyb3d8bbwe\winget.exe
    Path : C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.21.3421.0_x64__8wekyb3d8bbwe
  wt.exe
    (default) : C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.18.2822.0_x64__8wekyb3d8bbwe\wt.exe
    Path : C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.18.2822.0_x64__8wekyb3d8bbwe
HKLM
  7zFM.exe
    (default) : C:\Program Files\7-Zip\7zFM.exe
    Path : C:\Program Files\7-Zip\

    :
    :

  chrome.exe
    (default) : C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
    Path : C:\Program Files (x86)\Google\Chrome\Application

    :
    :

  firefox.exe
    (default) : C:\Program Files\Mozilla Firefox\firefox.exe
    Path : C:\Program Files\Mozilla Firefox

    :
    :

startコマンドは環境変数の "Path" に設定されたディレクトリと "App Paths" に設定されたファイル一覧から実行ファイル検索するようです。

なのでChromeの場合は "App Paths" に chrome.exe が設定されているので見つけることができ、メモ帳の場合は C:\WINDOWS\system32 が環境変数の "Path" に設定されているので見つけることができたというわけです。

startコマンドについては以上ですが、以下、関連する話もいくつかまとめてみました。

余談: 一時的な環境変数とエイリアス

各ブラウザは "App Paths" に値を設定していたのでパスを省略できていましたが、当然、環境変数に実行ファイルの親ディレクトリを追加することでもパスを省略できるようになります。

また、PowerShellにおいてはプロファイルを用いて一時的に環境変数に追記する、あるいはエイリアスを設定するという方法もあります。

# 方法1: 一時的に環境変数にパスを追加する
$env:Path += ";C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

# 方法2: エイリアスを設定する
Set-Alias chrome "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

この方法のメリットとして、例えば Excel や PowerPoint のようにコマンドラインオプションが存在するが環境変数にも "App Paths" にも設定されていないアプリを名前だけで呼び出すのに便利です。

Officeアプリのエイリアス追加
Set-Alias excel "C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
Set-Alias powerpnt "C:\Program Files\Microsoft Office\root\Office16\POWERPNT.EXE"
Set-Alias winword "C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE"

コマンドプロンプトでもsetコマンド・doskeyコマンドで一時的な環境変数の変更やエイリアスの設定が可能です。

@rem 方法1: 一時的に環境変数にパスを追加する
set path=%path$;C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

@rem 方法2: エイリアスを設定する
doskey chrome="C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

余談: Chromeの起動オプション

そもそもなぜChromeをコマンドラインで実行したかったかというと、Chromeに起動オプションを指定して起動させたかったという背景があります。

Chromeの起動オプションについては以下が詳しいです。

自分がよく使うのは --incognito--app の2つで、特に --app に関しては任意のサイトやローカルファイルをPWAのようにアドレスバーのないウィンドウで表示する目的でよく使っています。

# シークレットモードで開く
chrome "https://qiita.com/" --incognito

# アプリケーションモードで開く
chrome --app="https://qiita.com/"

# ブラウザをシンプルなPDFビューアとして起動する
chrome --app="file:///C:/Users/tacos/Desktop/sample.pdf" --incognito

この使い方についてはいずれ記事にしたいと思っています。

あと、同じChrome系のEdgeも上記のオプションを使うことができます。Safari/Firefoxはごめんなさい、知りません。

余談: PowerShellからの呼び出し

startコマンドとは の節でstartコマンドはPowerShellからは直接実行できないといいましたが、間接的になら呼び出せます。

cmd.exeの /c パラメータでコマンド文を渡して実行させることができるので、この機能を使います。

cmd /c "start chrome --app=`"https://qiita.com/`""

この方法であれば、仮にバージョンアップで C:\Program Files (x86)\Google\Chrome\Application というパスが別物に変わってしまっても関係なくブラウザを起動させることができます。

さいごに

startコマンドがブラウザ名、ひいてはアプリ名だけで実行ファイルを実行できる理由について解説してみました。

自分は今までユーザ環境変数のPathやPowerShellプロファイルでブラウザのパスを通すようにしていたんですけど、これがあるならもうパスを通す必要ないかもですね。

ただ、Windowsの組み込みコマンドや "App Paths" が廃止になってしまう可能性もゼロではないので、そこは気をつけたいところです。

記事は以上になります。最後まで読んでくださりありがとうございます。

8
4
2

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
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?