xlogI125’s blog

パソコン作業を効率化したい

C#からPowerShellコマンドを使う(PowerShell.AddScriptメソッド)

メモ

C#を使用可能でSystem.Management.Automation.dllを参照して良い場合にPowerShell.AddScriptメソッドを使う。

使い捨てスクリプト

# PowerShell 5.1, Windows 11 (2023年12月頃)

Set-StrictMode -Version Latest

$ps = [System.Management.Automation.PowerShell]::Create()
$null = $ps.AddScript('$gci = Get-ChildItem')
$null = $ps.AddScript('$gci | Out-GridView -Title "AddScript"')
$null = $ps.AddScript('$gci')
$ps.Invoke() | Out-GridView -Title "Invoke"
$ps.Dispose()
# PowerShell 5.1, Windows 11 (2023年12月頃)

Set-StrictMode -Version Latest

Add-Type -Language CSharp -TypeDefinition @'
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;

namespace ConsoleApp1 {
  public class Program {
    public static void Main(string[] args) {
      Collection<PSObject> psObjs;
      using (PowerShell ps = PowerShell.Create()) {
        ps.AddScript(@"Get-ChildITem | Format-Table | Out-String -Width 80");
        psObjs = ps.Invoke();
        foreach (PSObject psObj in psObjs) {
          Console.WriteLine("{0}", psObj);
        }

        ps.AddScript(@"$gci = Get-ChildITem ""c:\""");
        ps.AddScript(@"$gci | Out-GridView");
        ps.AddScript(@"$str = $gci | Format-Table | Out-String -Width 80");
        ps.AddScript(@"$str");
        psObjs = ps.Invoke();
        foreach (PSObject psObj in psObjs) {
          Console.WriteLine("{0}", psObj);
        }
      }
    }
  }
}
'@

[ConsoleApp1.Program]::Main($args)

過去記事

dy100ms.hatenadiary.jp

ファイル作成時に通知領域にアイコンを表示 2

メモ

  • NotifyIconFileSystemWatcherのイベントをRegister-ObjectEventでsubscribe
  • Icon.ExtractAssociatedIconSystemIconsのアイコンを使用

使い捨てスクリプト

デスクトップにファイルを作成したとき、通知領域にファイルのアイコンを表示する。
ショートカットなどの新規作成時にtmpファイルを拾うけど気にしない。

# PowerShell 5.1, Windows 11 (2023年11月頃)

Set-StrictMode -Version Latest

Add-Type -AssemblyName System.Drawing, System.Windows.Forms

$filePath = $null

$ntf = [System.Windows.Forms.NotifyIcon]::new()
$ntf.Icon = [System.Drawing.SystemIcons]::Information
$ntf.Text = "パスの末尾が表示されます"
$ntf.Visible = $true

Register-ObjectEvent -InputObject $ntf -EventName "Click" -Action {
  Set-Clipboard $filePath
  $ntf.Icon = [System.Drawing.SystemIcons]::Information
  $ntf.Text = "パスの末尾が表示されます"
}

$watcher = [System.IO.FileSystemWatcher]::new()
$watcher.Path = "${env:USERPROFILE}\Desktop"
$watcher.Filter = "*"
$watcher.IncludeSubdirectories = $true
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName

Register-ObjectEvent -InputObject $watcher -EventName "Created" -Action {
  ([ref]$filePath).Value = $EventArgs.FullPath

  $text = $filePath
  if ($text.Length -gt 63) { $text = $text.Substring($text.Length - 63) }

  try { $ntf.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($filePath) }
  catch { $ntf.Icon = [System.Drawing.SystemIcons]::Error }

  try { $ntf.Text = $text }
  catch { $ntf.Text = "最大文字数を超えています" }
}

ファイル作成時に通知領域にアイコンを表示

メモ

  • BalloonTipの表示
    • 設定 > システム > 通知 で 通知 を オン にしておく
    • 設定 > システム > 通知 で 応答不可 を オフ にしておく

使い捨てスクリプト

# PowerShell 5.1, Windows 11 (2023年11月頃)

$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue

Set-StrictMode -Version Latest

Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms

Add-Type -Language CSharp -TypeDefinition @'
namespace Win32API {
  using System;
  using System.Runtime.InteropServices;
  public class Winuser {
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool DestroyIcon(IntPtr hIcon);
  }
}
'@

$sbIcon = {
  param ([int]$colorR, [int]$colorG, [int]$colorB)

  $bmp = [System.Drawing.Bitmap]::new(16, 16)

  $g = [System.Drawing.Graphics]::FromImage($bmp)
  $g.FillRectangle(
    [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, $colorR, $colorG, $colorB)), 
    0, 0, $bmp.Width, $bmp.Height
  )
  $g.Dispose()

  $iconTmp = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
  $iconRet = [System.Drawing.Icon]::new($iconTmp, $iconTmp.Width, $iconTmp.Height)
  $null = [Win32API.Winuser]::DestroyIcon($iconTmp.Handle)
  $iconTmp.Dispose()

  $bmp.Dispose()

  return $iconRet
}

$ntf = [System.Windows.Forms.NotifyIcon]::new()

$ntf.Icon = & $sbIcon -colorR 0 -colorG 192 -colorB 0
$ntf.Text = "ToolTip テキスト"
$ntf.Visible = $true

$ntf.BalloonTipTitle = "BalloonTip タイトル"
$ntf.BalloonTipText = "BalloonTip テキスト"
$ntf.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
$ntf.ShowBalloonTip(3000)

# add_Clickメソッドの定義を表示
$ntf | Get-Member -Force

$ntf.add_Click({
  param ([object]$sender, [System.Windows.Forms.MouseEventArgs]$e)
  $sender.Visible = $false
})


$watcher = [System.IO.FileSystemWatcher]::new()
$watcher.Path = "${env:USERPROFILE}\Desktop"
$watcher.Filter = "*"
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName

Register-ObjectEvent -InputObject $watcher -EventName "Created" -Action {
  # Automatic Variables: $EventArgs

  $ntf.Icon = & $sbIcon -colorR 192 -colorG 0 -colorB 0
  $ntf.Text = [System.IO.Path]::GetFileName($EventArgs.FullPath)
  $ntf.Visible = $true

  $ntf.BalloonTipTitle = "Created"
  $ntf.BalloonTipText = $EventArgs.FullPath
  $ntf.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Info
  $ntf.ShowBalloonTip(3000)
}