ps1 ファイルをダブルクリックで実行する
◆ ダブルクリックで実行したいけど bat ファイルみたいに間違って実行するのは避けたい
◆ exe ファイルと違って実行するだけで不可逆な変更をするものが多い
◆ PowerShell 7 だと右クリックからなので良い感じだけどインストールが必要
◆ ダイアログで確認してから PowerShell を実行する exe ファイルを作って ps1 に関連付け
◆ ダブルクリックで実行できる
◆ 1 ファイルダウンロードするだけなので PowerShell インストールよりお手軽
◆ ps1 ファイル上にファイルやフォルダをドロップして引数にはできない
◆ exe ファイルと違って実行するだけで不可逆な変更をするものが多い
◆ PowerShell 7 だと右クリックからなので良い感じだけどインストールが必要
◆ ダイアログで確認してから PowerShell を実行する exe ファイルを作って ps1 に関連付け
◆ ダブルクリックで実行できる
◆ 1 ファイルダウンロードするだけなので PowerShell インストールよりお手軽
◆ ps1 ファイル上にファイルやフォルダをドロップして引数にはできない
ps1 ファイルの実行
ps1 ファイルはダブルクリックしても実行されません関連付けの設定で実行できそうですが それだけだとコマンドラインからの実行と同じで実行ポリシーに引っかかって実行できなそうです
実行ポリシーは全許可にもできるのですが 解除したらしたで bat ファイルと同じく間違って実行してしまう問題がおきます
exe はたいてい GUI アプリなので起動するだけだと何も起きません
間違って起動しても閉じればいいだけです
コマンドライン exe もありますがたいてい引数なしだと何もせず終わります
それに比べて bat や ps1 ファイルは実行したら即どこかに変化を起こす処理が多く 間違って実行してしまうのが怖いところです
上書き処理や削除など元に戻せないものもありますし
yes/no のプロンプトがあるものもありますが無いものもありますし 自作だと面倒で作らないことが多いです
PowerShell 7
.NET Core の PowerShell 7 だと インストールしてもダブルクリックは変化なく 右クリックメニューに「PowerShellで実行」というのが出てきますこっちだと新しい PowerShell (pwsh コマンド) で実行されていて こっちは実行ポリシーが緩くなっているので実行できます
右クリックメニューでもときどきズレてひとつ上のを押してしまうとかありますが 基本的にはこれで十分かなと思います
PowerShell 7 だと解決と思ってましたが デフォルトだと入ってないんですよね
使う PC 全部にインストールしていくのも疲れますし……
PowerShell を実行する exe を作る
Windows10 標準の PowerShell でもいい感じに実行できる方法を考えていると「ダブルクリックで実行するけど インストーラみたいに確認ダイアログ出すだけでも十分そう」と思ったので作ってみることにしましたexe ファイルを自作して ps1 ファイルをそれに関連付けます
exe ファイルの中では 確認ダイアログを出して実行するなら 引数に渡される ps1 ファイルを実行ポリシーの制限なしで実行します
お手軽ですね
これでも外部から PC に追加する必要があるのですが PowerShell 7 だとインストールが必要で時間も少しかかります
共有フォルダやネット上から 1 つ exe ファイルコピーしてくるだけでいいならこっちのほうがいいかなというところです
とりあえず C# で作りました
PowerShellExecutor の略で pse.exe という名前にしました
[pse.proj]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<DebugType Condition=" '$(Configuration)' == 'Release' ">None</DebugType>
</PropertyGroup>
</Project>
[Program.cs]
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace pse
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
MessageBox.Show("実行する ps1 ファイルを指定してください");
return;
}
var ps1 = args[0];
if (!ps1.EndsWith(".ps1"))
{
MessageBox.Show("ps1 ファイルを指定してください");
return;
}
var result = MessageBox.Show(
$"以下のファイルを実行しますか?\n{ps1}",
"PowerShellスクリプトの実行",
MessageBoxButtons.YesNo,
MessageBoxIcon.Asterisk
);
if (result != DialogResult.Yes) return;
var psi = new ProcessStartInfo("powershell.exe")
{
ArgumentList = {
"-NoProfile",
"-ExecutionPolicy",
"Unrestricted",
ps1
}
};
Process.Start(psi);
}
}
}
このコマンドで publish して exe ファイルを作ります
dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true --self-contained false
1 ファイルにできたのですが 考えてみると .NET5 のランタイムが必要です
それ入れるなら PowerShell 7 をインストールすれば良いと思うので このままだとあまり意味がないです
--self-contained を true にすればランタイム込みになるはずですが サイズが結構なものになりますし .NET Framework4.8 でビルドするのが安定でしょうか
(dotnet コマンドで .NET Framework 使えたっけ……?)
ps1 ファイルにドロップできない
使ってみて気づいたのですが ps1 ファイルにファイルなどをドロップできませんexe や bat ファイルみたいに ps1 ファイルにドロップできて ps1 ファイル自体とドロップしたファイルが pse.exe の引数になることを期待したのですができませんでした
考えてみると ps1 ファイルは txt ファイルや js ファイルなどと同じようなただのファイル扱いなので ps1 ファイル上にはドロップできないですよね
引数にファイルやフォルダを受け取る前提の ps1 ファイルでは使えないので 使いどころは思っていたより少なそうです
bat ファイルやショートカットを経由すればドロップしたファイルを引数にできますが それだと ps1 ファイルごとに bat ファイルやショートカットを作ることになります
それが面倒なので避けたくてダブルクリックで実行できるようにしたので 意味がないんですよね
「ダブルクリックで ps1 ファイルの実行+実行前にダイアログで確認」って探せば標準機能の設定できてもよさそうなものですし ドロップ可能な方法ないのかな