Introduction
ArtisanはLaravelに含まれるコマンドラインインターフェースです。Artisanはアプリケーションのルートにartisan
スクリプトとして存在し、アプリケーションを構築する際に役立つ多くのコマンドを提供します。利用可能なすべてのArtisanコマンドのリストを表示するには、list
コマンドを使用します:
php artisan list
すべてのコマンドには、コマンドの利用可能な引数とオプションを表示し説明する「help」画面が含まれています。ヘルプ画面を表示するには、コマンド名の前にhelp
を付けます:
php artisan help migrate
Laravel Sail
ローカル開発環境としてLaravel Sailを使用している場合は、sail
コマンドラインを使用してArtisanコマンドを呼び出すことを忘れないでください。Sailは、アプリケーションのDockerコンテナ内でArtisanコマンドを実行します:
./vendor/bin/sail artisan list
Tinker (REPL)
Laravel Tinkerは、PsySHパッケージによって提供されるLaravelフレームワークの強力なREPLです。
Installation
すべてのLaravelアプリケーションにはデフォルトでTinkerが含まれています。ただし、以前にアプリケーションから削除した場合は、Composerを使用してTinkerをインストールできます:
composer require laravel/tinker
Laravelアプリケーションと対話する際にホットリロード、マルチラインコード編集、オートコンプリートを探していますか?Tinkerwellをチェックしてください!
Usage
Tinkerを使用すると、Eloquentモデル、ジョブ、イベントなどを含むLaravelアプリケーション全体とコマンドラインで対話できます。Tinker環境に入るには、tinker
Artisanコマンドを実行します:
php artisan tinker
Tinkerの設定ファイルをvendor:publish
コマンドを使用して公開できます:
php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"
<a name="command-allow-list"></a>
#### Command Allow List
Tinkerは、Artisanコマンドがそのシェル内で実行できるかどうかを判断するために「許可」リストを利用します。デフォルトでは、`````clear-compiled`````、`````down`````、`````env`````、`````inspire`````、`````migrate`````、`````migrate:install`````、`````up`````、`````optimize`````コマンドを実行できます。さらにコマンドを許可したい場合は、`````commands`````配列に追加できます。`````tinker.php`````設定ファイル:
``````php
'commands' => [
// App\Console\Commands\ExampleCommand::class,
],
`
Classes That Should Not Be Aliased
通常、Tinkerは、Tinker内で対話する際にクラスを自動的にエイリアスします。ただし、一部のクラスをエイリアスしないようにしたい場合があります。これを実現するには、dont_alias
配列にクラスをリストします。tinker.php
設定ファイル:
'dont_alias' => [
App\Models\User::class,
],
Writing Commands
Artisanで提供されるコマンドに加えて、独自のカスタムコマンドを作成できます。コマンドは通常app/Console/Commands
ディレクトリに保存されますが、Composerによって読み込まれる限り、独自のストレージ場所を選択することもできます。
Generating Commands
新しいコマンドを作成するには、make:command
Artisanコマンドを使用します。このコマンドは、app/Console/Commands
ディレクトリに新しいコマンドクラスを作成します。このディレクトリがアプリケーションに存在しない場合でも心配しないでください - make:command
Artisanコマンドを初めて実行するときに作成されます:
php artisan make:command SendEmails
Command Structure
コマンドを生成した後、クラスのsignature
およびdescription
プロパティに適切な値を定義する必要があります。これらのプロパティは、list
画面にコマンドを表示する際に使用されます。signature
プロパティを使用すると、コマンドの入力期待値を定義できます。handle
メソッドは、コマンドが実行されるときに呼び出されます。このメソッドにコマンドロジックを配置できます。
例のコマンドを見てみましょう。コマンドのhandle
メソッドを介して必要な依存関係を要求できることに注意してください。Laravelのサービスコンテナは、このメソッドのシグネチャに型ヒントされたすべての依存関係を自動的に注入します:
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Send a marketing email to a user';
/**
* Execute the console command.
*/
public function handle(DripEmailer $drip): void
{
$drip->send(User::find($this->argument('user')));
}
}
コードの再利用を高めるために、コンソールコマンドを軽量に保ち、アプリケーションサービスにタスクを委任することが良いプラクティスです。上記の例では、メールを送信する「重い作業」を行うためにサービスクラスを注入していることに注意してください。
Exit Codes
``````php
$this->error('Something went wrong.');
return 1;
`
コマンド内の任意のメソッドからコマンドを「失敗」させたい場合は、fail
メソッドを利用できます。fail
メソッドは、コマンドの実行を即座に終了し、1
の終了コードを返します:
$this->fail('Something went wrong.');
Closure Commands
クロージャベースのコマンドは、コンソールコマンドをクラスとして定義する代替手段を提供します。ルートクロージャがコントローラーの代替手段であるのと同じように、コマンドクロージャはコマンドクラスの代替手段と考えてください。
``````php
Artisan::command('mail:send {user}', function (string $user) {
$this->info("Sending email to: {$user}!");
});
`
クロージャは基盤となるコマンドインスタンスにバインドされているため、通常のコマンドクラスでアクセスできるすべてのヘルパーメソッドに完全にアクセスできます。
Type-Hinting Dependencies
コマンドの引数とオプションを受け取るだけでなく、コマンドクロージャは、サービスコンテナから解決したい追加の依存関係を型ヒントすることもできます:
use App\Models\User;
use App\Support\DripEmailer;
Artisan::command('mail:send {user}', function (DripEmailer $drip, string $user) {
$drip->send(User::find($user));
});
Closure Command Descriptions
クロージャベースのコマンドを定義する際に、purpose
メソッドを使用してコマンドに説明を追加できます。この説明は、php artisan list
またはphp artisan help
コマンドを実行したときに表示されます:
Artisan::command('mail:send {user}', function (string $user) {
// ...
})->purpose('Send a marketing email to a user');
Isolatable Commands
この機能を利用するには、アプリケーションがmemcached
、redis
、dynamodb
、database
、file
、またはarray
キャッシュドライバーをデフォルトのキャッシュドライバーとして使用している必要があります。さらに、すべてのサーバーは同じ中央キャッシュサーバーと通信している必要があります。
時には、コマンドのインスタンスが同時に1つだけ実行できることを確認したい場合があります。これを実現するには、コマンドクラスでIlluminate\Contracts\Console\Isolatable
インターフェースを実装します:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Isolatable;
class SendEmails extends Command implements Isolatable
{
// ...
}
コマンドがIsolatable
としてマークされると、Laravelは自動的にコマンドに--isolated
オプションを追加します。そのオプションでコマンドが呼び出されると、Laravelはそのコマンドの他のインスタンスがすでに実行されていないことを確認します。Laravelは、アプリケーションのデフォルトキャッシュドライバーを使用して原子的なロックを取得しようとすることでこれを実現します。他のインスタンスのコマンドが実行されている場合、コマンドは実行されませんが、コマンドは成功の終了ステータスコードで終了します:
php artisan mail:send 1 --isolated
コマンドが実行できない場合に返すべき終了ステータスコードを指定したい場合は、isolated
オプションを介して希望のステータスコードを提供できます:
php artisan mail:send 1 --isolated=12
Lock ID
デフォルトでは、Laravelはコマンドの名前を使用して、アプリケーションのキャッシュで原子的なロックを取得するために使用される文字列キーを生成します。ただし、isolatableId
メソッドをArtisanコマンドクラスに定義することで、このキーをカスタマイズできます。これにより、コマンドの引数やオプションをキーに統合できます:
/**
* Get the isolatable ID for the command.
*/
public function isolatableId(): string
{
return $this->argument('user');
}
Lock Expiration Time
デフォルトでは、隔離ロックはコマンドが終了すると期限切れになります。また、コマンドが中断されて終了できない場合、ロックは1時間後に期限切れになります。ただし、コマンドにisolationLockExpiresAt
メソッドを定義することで、ロックの有効期限を調整できます:
use DateTimeInterface;
use DateInterval;
/**
* Determine when an isolation lock expires for the command.
*/
public function isolationLockExpiresAt(): DateTimeInterface|DateInterval
{
return now()->addMinutes(5);
}
Defining Input Expectations
コンソールコマンドを書くとき、引数やオプションを通じてユーザーからの入力を収集することは一般的です。Laravelは、コマンドのsignature
プロパティを使用して、ユーザーから期待する入力を定義するのを非常に便利にします。signature
プロパティを使用すると、コマンドの名前、引数、およびオプションを単一の表現力豊かなルートのような構文で定義できます。
Arguments
すべてのユーザー提供の引数とオプションは波括弧で囲まれています。次の例では、コマンドは1つの必須引数を定義します:user
:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';
引数をオプションにしたり、引数のデフォルト値を定義したりすることもできます:
// Optional argument...
'mail:send {user?}'
// Optional argument with default value...
'mail:send {user=foo}'
Options
オプションは引数と同様に、ユーザー入力の別の形式です。オプションは、コマンドラインで提供されるときに2つのハイフン(--
)で接頭辞が付けられます。オプションには、値を受け取るものと受け取らないものの2種類があります。値を受け取らないオプションは、ブール値の「スイッチ」として機能します。このタイプのオプションの例を見てみましょう:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue}';
この例では、--queue
スイッチはArtisanコマンドを呼び出すときに指定できます。--queue
スイッチが渡されると、オプションの値はtrue
になります。そうでなければ、値はfalse
になります:
php artisan mail:send 1 --queue
Options With Values
次に、値を期待するオプションを見てみましょう。ユーザーがオプションの値を指定する必要がある場合、オプション名の後に=
記号を付ける必要があります:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue=}';
この例では、ユーザーは次のようにオプションの値を渡すことができます。コマンドを呼び出すときにオプションが指定されない場合、その値はnull
になります:
php artisan mail:send 1 --queue=default
オプション名の後にデフォルト値を指定することで、オプションにデフォルト値を割り当てることができます。ユーザーがオプション値を渡さない場合、デフォルト値が使用されます:
'mail:send {user} {--queue=default}'
Option Shortcuts
オプションを定義するときにショートカットを割り当てるには、オプション名の前に指定し、|
文字を区切り文字として使用してショートカットと完全なオプション名を分けます:
'mail:send {user} {--Q|queue}'
ターミナルでコマンドを呼び出すとき、オプションショートカットは単一のハイフンで接頭辞が付けられ、オプションの値を指定するときに=
文字は含めないでください:
php artisan mail:send 1 -Qdefault
Input Arrays
複数の入力値を期待する引数やオプションを定義したい場合は、*
文字を使用できます。まず、そのような引数を指定する例を見てみましょう:
'mail:send {user*}'
このメソッドを呼び出すとき、user
引数をコマンドラインに順番に渡すことができます。たとえば、次のコマンドはuser
の値を1
と2
を値とする配列に設定します:
php artisan mail:send 1 2
この*
文字は、引数のオプション定義と組み合わせて、引数のインスタンスを0個以上許可することができます:
'mail:send {user?*}'
Option Arrays
複数の入力値を期待するオプションを定義する場合、コマンドに渡される各オプション値はオプション名で接頭辞が付けられる必要があります:
'mail:send {--id=*}'
このようなコマンドは、複数の--id
引数を渡すことで呼び出すことができます:
php artisan mail:send --id=1 --id=2
Input Descriptions
入力引数やオプションに説明を割り当てるには、引数名と説明をコロンで区切ります。コマンドを定義するために少し余分なスペースが必要な場合は、定義を複数行に分けて記述してください:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send
{user : The ID of the user}
{--queue : Whether the job should be queued}';
Prompting for Missing Input
コマンドに必須引数が含まれている場合、提供されないとユーザーはエラーメッセージを受け取ります。あるいは、PromptsForMissingInput
インターフェースを実装することで、必須引数が欠落しているときに自動的にユーザーにプロンプトを表示するようにコマンドを構成できます:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;
class SendEmails extends Command implements PromptsForMissingInput
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';
// ...
}
Laravelがユーザーから必須引数を収集する必要がある場合、引数名または説明を使用して質問を知的に表現することで、ユーザーに自動的に質問します。必要に応じて、必須引数を収集するために使用される質問をカスタマイズするには、promptForMissingArgumentsUsing
メソッドを実装し、引数名でキー付けされた質問の配列を返します:
/**
* Prompt for missing input arguments using the returned questions.
*
* @return array<string, string>
*/
protected function promptForMissingArgumentsUsing(): array
{
return [
'user' => 'Which user ID should receive the mail?',
];
}
質問とプレースホルダを含むタプルを使用してプレースホルダテキストを提供することもできます:
return [
'user' => ['Which user ID should receive the mail?', 'E.g. 123'],
];
プロンプトを完全に制御したい場合は、ユーザーにプロンプトを表示し、回答を返すクロージャを提供できます:
use App\Models\User;
use function Laravel\Prompts\search;
// ...
return [
'user' => fn () => search(
label: 'Search for a user:',
placeholder: 'E.g. Taylor Otwell',
options: fn ($value) => strlen($value) > 0
? User::where('name', 'like', "%{$value}%")->pluck('name', 'id')->all()
: []
),
];
包括的なLaravel Promptsドキュメントには、利用可能なプロンプトとその使用法に関する追加情報が含まれています。
ユーザーにオプションを選択または入力するようにプロンプトを表示したい場合は、コマンドのhandle
メソッドにプロンプトを含めることができます。ただし、ユーザーが欠落している引数のために自動的にプロンプトが表示されたときにのみプロンプトを表示したい場合は、afterPromptingForMissingArguments
メソッドを実装できます:
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\confirm;
// ...
/**
* Perform actions after the user was prompted for missing arguments.
*/
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void
{
$input->setOption('queue', confirm(
label: 'Would you like to queue the mail?',
default: $this->option('queue')
));
}
Command I/O
Retrieving Input
コマンドが実行されている間、コマンドが受け入れる引数やオプションの値にアクセスする必要があるでしょう。そのためには、argument
およびoption
メソッドを使用できます。引数やオプションが存在しない場合、null
が返されます:
/**
* Execute the console command.
*/
public function handle(): void
{
$userId = $this->argument('user');
}
すべての引数をarray
として取得するには、arguments
メソッドを呼び出します:
$arguments = $this->arguments();
オプションは、option
メソッドを使用して引数と同様に簡単に取得できます。すべてのオプションを配列として取得するには、options
メソッドを呼び出します:
// Retrieve a specific option...
$queueName = $this->option('queue');
// Retrieve all options as an array...
$options = $this->options();
Prompting for Input
Laravel Promptsは、ブラウザのような機能を持つ美しくユーザーフレンドリーなフォームをコマンドラインアプリケーションに追加するためのPHPパッケージです。プレースホルダテキストやバリデーションを含みます。
出力を表示するだけでなく、コマンドの実行中にユーザーに入力を提供するように求めることもできます。ask
メソッドは、指定された質問でユーザーにプロンプトを表示し、入力を受け入れ、その後ユーザーの入力をコマンドに返します:
/**
* Execute the console command.
*/
public function handle(): void
{
$name = $this->ask('What is your name?');
// ...
}
``````php
$name = $this->ask('What is your name?', 'Taylor');
`
``````php
$password = $this->secret('What is the password?');
`
Asking for Confirmation
ユーザーにシンプルな「はいまたはいいえ」の確認を求める必要がある場合、confirm
メソッドを使用できます。デフォルトでは、このメソッドはfalse
を返します。ただし、ユーザーがプロンプトにy
またはyes
と入力した場合、メソッドはtrue
を返します。
if ($this->confirm('Do you wish to continue?')) {
// ...
}
必要に応じて、confirm
メソッドの第2引数としてtrue
を渡すことで、確認プロンプトがデフォルトでtrue
を返すように指定できます:
if ($this->confirm('Do you wish to continue?', true)) {
// ...
}
Auto-Completion
``````php
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
`
代わりに、anticipate
メソッドの第2引数としてクロージャを渡すことができます。ユーザーが入力文字をタイプするたびにクロージャが呼び出されます。クロージャは、ユーザーの現在の入力を含む文字列パラメータを受け取り、オートコンプリートのオプションの配列を返す必要があります:
$name = $this->anticipate('What is your address?', function (string $input) {
// Return auto-completion options...
});
Multiple Choice Questions
質問をする際にユーザーに事前定義された選択肢を提供する必要がある場合、choice
メソッドを使用できます。オプションが選択されない場合に返されるデフォルト値の配列インデックスを、メソッドの第3引数として渡すことができます:
$name = $this->choice(
'What is your name?',
['Taylor', 'Dayle'],
$defaultIndex
);
さらに、choice
メソッドは、正しい応答を選択するための最大試行回数を決定するためのオプションの第4および第5引数を受け入れ、複数の選択が許可されているかどうかを決定します:
$name = $this->choice(
'What is your name?',
['Taylor', 'Dayle'],
$defaultIndex,
$maxAttempts = null,
$allowMultipleSelections = false
);
Writing Output
コンソールに出力を送信するには、line
、info
、comment
、question
、warn
、およびerror
メソッドを使用できます。これらのメソッドは、それぞれの目的に応じたANSI色を使用します。たとえば、ユーザーに一般的な情報を表示しましょう。通常、info
メソッドは緑色のテキストとしてコンソールに表示されます:
/**
* Execute the console command.
*/
public function handle(): void
{
// ...
$this->info('The command was successful!');
}
エラーメッセージを表示するには、error
メソッドを使用します。エラーメッセージのテキストは通常赤色で表示されます:
$this->error('Something went wrong!');
``````php
$this->line('Display this on the screen');
`
``````php
// Write a single blank line...
$this->newLine();
// Write three blank lines...
$this->newLine(3);
`
Tables
``````php
use App\Models\User;
$this->table(
['Name', 'Email'],
User::all(['name', 'email'])->toArray()
);
`
Progress Bars
長時間実行されるタスクでは、タスクの完了度をユーザーに知らせるプログレスバーを表示することが役立ちます。withProgressBar
メソッドを使用すると、Laravelはプログレスバーを表示し、指定された反復値ごとに進捗を進めます:
use App\Models\User;
$users = $this->withProgressBar(User::all(), function (User $user) {
$this->performTask($user);
});
時には、プログレスバーの進行方法を手動で制御する必要があります。まず、プロセスが反復する総ステップ数を定義します。次に、各アイテムを処理した後にプログレスバーを進めます:
$users = App\Models\User::all();
$bar = $this->output->createProgressBar(count($users));
$bar->start();
foreach ($users as $user) {
$this->performTask($user);
$bar->advance();
}
$bar->finish();
詳細なオプションについては、Symfony Progress Barコンポーネントのドキュメントを確認してください。
Registering Commands
デフォルトでは、Laravelはapp/Console/Commands
ディレクトリ内のすべてのコマンドを自動的に登録します。ただし、withCommands
メソッドを使用して、Artisanコマンドのために他のディレクトリをスキャンするようにLaravelに指示できます。アプリケーションのbootstrap/app.php
ファイル:
->withCommands([
__DIR__.'/../app/Domain/Orders/Commands',
])
必要に応じて、withCommands
メソッドにコマンドのクラス名を提供することで、コマンドを手動で登録することもできます:
use App\Domain\Orders\Commands\SendEmails;
->withCommands([
SendEmails::class,
])
Artisanが起動すると、アプリケーション内のすべてのコマンドがサービスコンテナによって解決され、Artisanに登録されます。
Programmatically Executing Commands
時には、CLIの外でArtisanコマンドを実行したい場合があります。たとえば、ルートやコントローラーからArtisanコマンドを実行したい場合があります。call
メソッドをArtisan
ファサードで使用してこれを実現できます。call
メソッドは、コマンドのシグネチャ名またはクラス名を最初の引数として受け取り、コマンドパラメータの配列を第2引数として受け取ります。終了コードが返されます:
use Illuminate\Support\Facades\Artisan;
Route::post('/user/{user}/mail', function (string $user) {
$exitCode = Artisan::call('mail:send', [
'user' => $user, '--queue' => 'default'
]);
// ...
});
代わりに、Artisanコマンド全体をcall
メソッドに文字列として渡すこともできます:
Artisan::call('mail:send 1 --queue=default');
Passing Array Values
コマンドが配列を受け入れるオプションを定義している場合、そのオプションに値の配列を渡すことができます:
use Illuminate\Support\Facades\Artisan;
Route::post('/mail', function () {
$exitCode = Artisan::call('mail:send', [
'--id' => [5, 13]
]);
});
Passing Boolean Values
文字列値を受け入れないオプションの値を指定する必要がある場合、--force
フラグをmigrate:refresh
コマンドで使用する場合、true
またはfalse
をオプションの値として渡す必要があります:
$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);
Queueing Artisan Commands
``````php
use Illuminate\Support\Facades\Artisan;
Route::post('/user/{user}/mail', function (string $user) {
Artisan::queue('mail:send', [
'user' => $user, '--queue' => 'default'
]);
// ...
});
`
``````php
Artisan::queue('mail:send', [
'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');
`
Calling Commands From Other Commands
時には、既存のArtisanコマンドから他のコマンドを呼び出したい場合があります。call
メソッドを使用してこれを行うことができます。このcall
メソッドは、コマンド名とコマンド引数/オプションの配列を受け取ります:
/**
* Execute the console command.
*/
public function handle(): void
{
$this->call('mail:send', [
'user' => 1, '--queue' => 'default'
]);
// ...
}
他のコンソールコマンドを呼び出し、その出力をすべて抑制したい場合は、callSilently
メソッドを使用できます。callSilently
メソッドはcall
メソッドと同じシグネチャを持っています:
$this->callSilently('mail:send', [
'user' => 1, '--queue' => 'default'
]);
Signal Handling
オペレーティングシステムは、実行中のプロセスに信号を送信することを許可します。たとえば、SIGTERM
信号は、オペレーティングシステムがプログラムに終了を要求する方法です。Artisanコンソールコマンドで信号をリッスンし、それらが発生したときにコードを実行したい場合は、trap
メソッドを使用できます:
/**
* Execute the console command.
*/
public function handle(): void
{
$this->trap(SIGTERM, fn () => $this->shouldKeepRunning = false);
while ($this->shouldKeepRunning) {
// ...
}
}
複数の信号を同時にリッスンするには、trap
メソッドに信号の配列を提供できます:
$this->trap([SIGTERM, SIGQUIT], function (int $signal) {
$this->shouldKeepRunning = false;
dump($signal); // SIGTERM / SIGQUIT
});
Stub Customization
Artisanコンソールのmake
コマンドは、コントローラー、ジョブ、マイグレーション、テストなどのさまざまなクラスを作成するために使用されます。これらのクラスは、入力に基づいて値が埋め込まれた「スタブ」ファイルを使用して生成されます。ただし、Artisanによって生成されたファイルに小さな変更を加えたい場合があります。これを実現するには、stub:publish
コマンドを使用して、最も一般的なスタブをアプリケーションに公開し、カスタマイズできるようにします:
php artisan stub:publish
公開されたスタブは、アプリケーションのルートにあるstubs
ディレクトリ内に配置されます。これらのスタブに加えた変更は、Artisanのmake
コマンドを使用して対応するクラスを生成するときに反映されます。
Events
Artisanはコマンドを実行する際に3つのイベントを発行します:Illuminate\Console\Events\ArtisanStarting
、Illuminate\Console\Events\CommandStarting
、およびIlluminate\Console\Events\CommandFinished
。ArtisanStarting
イベントは、Artisanが実行を開始したときに即座に発行されます。次に、CommandStarting
イベントは、コマンドが実行される直前に即座に発行されます。最後に、CommandFinished
イベントは、コマンドの実行が完了したときに発行されます。