UWSCをPowerShellに移植してみた

僕は、ShortcutExecutorを使って、「Windowsキー+何か」に色々割り振っています。

例えば、Win + P で Poderosa が起動 or すでに起動していたらアクティブ&最大化するようにしています。

いつもは、ShortcutExecutor から UWSCスクリプトをたたいているんですが、UWSC の起動が微妙に遅いので、PowerShell に移植してみました。でも、PowerShell の方が遅かった。orz

破棄するのも、もったいないので、ここに、残骸を残しておきます。

UWSC 版(いつも使っているやつ)。poderosa.uws で保存して、実行してください。

isFound = false
for i = 0 to GETALLWIN() - 1
	titleName = STATUS(ALL_WIN_ID[i], ST_TITLE)
	ifb titleName = "Poderosa" or POS(" - Poderosa", titleName) <> 0 then
		CTRLWIN(ALL_WIN_ID[i], MAX)
		CTRLWIN(ALL_WIN_ID[i], ACTIVATE)
		isFound = true
		break
	endif
next
ifb !isFound then
	EXEC("C:\Program Files\Poderosa\Poderosa.exe")
endif

PowerShell

以下を、poderosa.ps1 と保存して、PowerShell.exe .\poderosa.ps1 で実行してください。前半の方は、PowerShellからWin32APIを呼ぶ - 潜在推力 で書かれている、Win32 API を呼び出すための関数です。

# http://d.hatena.ne.jp/ps1/20080312/1205339720

function New-PType() {
  [AppDomain]::CurrentDomain.DefineDynamicAssembly(
    (New-Object Reflection.AssemblyName 'PInvokeAssembly'), 'Run'
  ).DefineDynamicModule('PInvokeModule').DefineType('PInvokeType', "Public,BeforeFieldInit")
}

# DLL名, 戻り値の型, メソッド名, 引数の型
function New-PMethod([string]$dll_name, [Type]$return_type, [string]$method_name, [Type[]]$parameter_types){
  $ptype = New-PType
  $ptype.DefineMethod(
    $method_name, 'Public,HideBySig,Static,PinvokeImpl', $return_type, $parameter_types
  ).SetCustomAttribute(
    (New-Object Reflection.Emit.CustomAttributeBuilder ([Runtime.InteropServices.DllImportAttribute].GetConstructor([string])), $dll_name)
  )

  # apiにメンバーを追加
  $invoke  = {
    for($i = 0; $i -lt $this.ParameterTypes.Length; $i++){ $args[$i] = $args[$i] -as $this.ParameterTypes[$i] }
    return $this.InvokeMember($this.MethodName, 'Public,Static,InvokeMethod', $null, $null, $args)
  }
  $api = $ptype.CreateType() 
  $api =
  Add-Member -InputObject $api -MemberType NoteProperty -Name MethodName     -Value $method_name -passthru
  Add-Member -InputObject $api -MemberType NoteProperty -Name ParameterTypes -Value $parameter_types
  Add-Member -InputObject $api -MemberType ScriptMethod -Name Invoke         -Value $invoke
  return $api
}

# ---------------------------------------------------------------------------------------------------

$showWindow          = New-PMethod "user32.dll" ([Bool]) "ShowWindow"          @([IntPtr], [Int32])
$setForegroundWindow = New-PMethod "user32.dll" ([Bool]) "SetForegroundWindow" @([IntPtr])

$SC_MINIMIZE = 61472
$SC_MAXIMIZE = 61488
$SC_RESTORE  = 61728

# ---------------------------------------------------------------------------------------------------

$isFound = $False
foreach ($p in Get-Process) {
	if (($p.MainWindowTitle -eq "Poderosa") -or ($p.MainWindowTitle -like "* - Poderosa")) {
		$isFound = $True
		$b = $showWindow.Invoke($p.MainWindowHandle, $SC_MAXIMIZE)
		$b = $setForegroundWindow.Invoke($p.MainWindowHandle);
		break
	}
}
if (-! $isFound) {
	Invoke-Item "C:\Program Files\Poderosa\Poderosa.exe"
}