Skip to content

Instantly share code, notes, and snippets.

@advanceboy
Last active April 18, 2024 16:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save advanceboy/674407fc5bb23ddfc51b73e670b501c8 to your computer and use it in GitHub Desktop.
Save advanceboy/674407fc5bb23ddfc51b73e670b501c8 to your computer and use it in GitHub Desktop.
クリックされたら -Script オプションで指定したスクリプトを実行する、 タスクトレイのアイコンを登録します。 PowerShell 3~5, 7 で動作確認済み。
<###############################################################
タスクトレイに常駐し、クリックされると特定のスクリプトを実行するコード
###############################################################>
#Requires -Version 3
param(
# アイコンクリック時に実行する スクリプトファイル または スクリプトブロック
[parameter(Mandatory)]
[ValidateNotNull()]
[ValidateScript({ $_ -is [string] -or $_ -is [scriptblock] })]
$Script,
# アイコンの色。初期値は 0x0000007F (#00007F)。
# 同じ色を指定した場合、同時に起動できなくなる。
# ARGB<31-24> (不透明度) は無視される
# ARGB<23-16> は R
# ARGB<15-8> は G
# ARGB<7-0> は B
[ValidateNotNull()]
[uint32]$ARGB = 0x0000007F,
# アイコンのツールチップテキスト
[string]
$ToolHintText = $null
);
Add-Type -AssemblyName System.Windows.Forms;
# PowerShellっぽい アイコン画像バイナリ。
# 0x3f から 3バイト (PNG の PLTE チャンク) に、 RGB の順番で入っている背景色の色情報を書き換える。
$mems = New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String('AAABAAEAEBAQAAEABAB4AAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAEDAAAAJT1tIgAAAAZQTFRFAAB/////8DxOgwAAAC1JREFUCNdjYGBgYGFg4GNgYGdgYG5gYGxgYHgARcwHQIJyDAwWNQwGNQxgAACDjAYG7YuK+QAAAABJRU5ErkJggg=='));
$mems.Seek(0x3f, [System.IO.SeekOrigin]::Begin) > $null;
$ARGB = $ARGB -band 0x00ffffff;
$mems.WriteByte($ARGB -shr 16 -band 0xff);
$mems.WriteByte($ARGB -shr 8 -band 0xff);
$mems.WriteByte($ARGB -band 0xff);
$mems.Seek(0x0, [System.IO.SeekOrigin]::Begin) > $null;
$icon = New-Object System.Drawing.Icon($mems);
$MUTEX_NAME = '0b72e703-1de1-4320-ae81-d7c48257e460: ' + [System.BitConverter]::ToString([System.BitConverter]::GetBytes($ARGB));
$mutex = New-Object System.Threading.Mutex($false, $MUTEX_NAME);
try {
# 多重起動チェック
if ($mutex.WaitOne(0, $false)) {
try {
# コンテキスト作成
$appContext = New-Object System.Windows.Forms.ApplicationContext;
# 通知アイコン作成
$notifyIcon = [System.Windows.Forms.NotifyIcon]@{
Icon = $icon;
Text = $ToolHintText;
BalloonTipIcon = 'Error';
BalloonTipTitle = 'Error';
};
# アイコン左クリック時
$notifyIcon.add_Click({
if ($_.Button -eq [System.Windows.Forms.MouseButtons]::Left) {
try {
&$Script;
} catch {
$notifyIcon.BalloonTipText = $_.ToString();
$notifyIcon.ShowBalloonTip(5000);
}
}
});
# Exit メニュー
$menuItem = [System.Windows.Forms.ToolStripMenuItem]@{ Text = 'Exit' };
$notifyIcon.ContextMenuStrip = New-Object System.Windows.Forms.ContextMenuStrip;
[void]$notifyIcon.ContextMenuStrip.Items.Add($menuItem);
$menuItem.add_Click({
$appContext.ExitThread();
});
# 表示
$notifyIcon.Visible = $true;
[void][System.Windows.Forms.Application]::Run($appContext);
$notifyIcon.Visible = $false;
} finally {
$notifyIcon.Dispose();
$mutex.ReleaseMutex();
}
$retcode = 0;
} else {
$retcode = 255;
}
} finally {
$mutex.Dispose();
}
exit $retcode;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment