Powershellをランチャーにする
長らく、コマンドプロンプトをランチャーとして使ってきたのですが、XPの寿命も尽きようとしているので、Powershellに引っ越すことにしました。
いろいろ便利ですから!
CUIランチャーとして使うためにやったことのメモです。
今までのCUIランチャー
コマンドプロンプトをconsoleというタイトルで起動。
「kterm」と入力すると別ウインドウを立ち上げる。
よく使うプログラムにはaliasをつけておく。
「kterm」の「logout」はウインドウを閉じるだけ。
「console」の「logout」はPCをシャットダウンする。
こんな感じです。
aliasはPowershellの機能にありますから、kterm/logoutの工夫ですね。
ついでに「ls」の表示を好みにしました。
色つき嬉しい!(ハードコードだから変更はスクリプト修正)
「ls -l」「ls -la」あたりも通るように。
あとは、「rm」では確認を、「rm -f」で無条件削除に変更。
確認は-Confirmだとデフォルト「はい」を避けたいので、車輪の再発明。
「-r」オプションもなんとなく実装。
Powershell起動時の設定と言えば?
$profileですね。
Set-ExecutionPolicy は RemoteSigned あたりで。
notepad $profile でこれだけ書きました。
# modules # $env:USERPROFILE\Documents\WindowsPowerShell\Modules Import-Module -name login Import-Module -name logout # settings Remove-Item -Path alias:ls Remove-Item -Path alias:rm
$profileに何もかも書いてもよかったのですが、ま、可読性等です。
Module内でAllScopeのAliasを消す方法が不明です、、、。
loginモジュール
2014/01/27 いろいろくっつけて、あと管理者権限の表示に対応した。
function Start-Host() { Param( [string]$Title = "kterm", [switch]$Edit ) if($Edit) { iex "$EDITOR $env:USERPROFILE\Documents\WindowsPowerShell\Modules\login\login.psm1" } else { if((New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { $Title += " : admin" } (Get-Host).UI.RawUI.WindowTitle = $Title if($Title -match '^console(?: .*)?$') { #start mail } } } function Get-Types() { Param( [string]$Match, [string]$Name, [switch]$Private ) $res = @() if($Name.length -gt 0 -and $Name -as [Type]) { $res += ($Name -as [type]) } if($res.length -eq 0) { if($Match.length -le 0 -and $Name.length -gt 0) { $res = $Name -split '\.' $Match = '^' + $res[$res.length - 1] + '$' $res = @() } foreach($ass in [AppDomain]::CurrentDomain.GetAssemblies()) { foreach($t in $ass.GetTypes()) { if(($t.IsPublic -or $Private) -and ($t.Name -match $Match)) { $res += $t } } } } return $res } function Get-TypeMember() { Param( $Target, [switch]$Static, [switch]$Private ) if($Target -is [String]) { if($Target -match '^\[[^\]]+]$') { $Target = (($Target -replace '^\[([^\]]+)]$', '$1') -as [type]) } else { $ts = (Get-Types $Target) if($ts -ne $null -and -not $ts.length) { $Target = $ts } elseif(!$ts.length) { Write-Error ($Target + ' is not found!') $Target = $null } else { $ts | %{ Write-Host ('[' + $_.FullName + ']') } return Get-TypeMember (Read-Host ?) } } } $res = @() if($Target -is [Type]) { function getMembersSub($tar, [string]$para, [string]$pre) { function getTypeName($type) { $res = $type.ToString() $res = $res -replace 'System.Boolean', 'bool' $res = $res -replace 'System.String', 'string' $res = $res -replace 'System.Int32', 'int' $res = $res -replace 'System.Char', 'char' return $res } $res = @() foreach($mi in $tar.GetMembers($para)) { $def = '' if(-not $mi.IsPublic -and ($mi.MemberType -ne 'Property' -and $mi.MemberType -ne 'NestedType')) { $def = '# ' } $def += $pre $type = $mi.MemberType.ToString() switch($type) { Method { $def += (getTypeName $mi.ReturnType) + ' ' + $mi.Name + '(' $comma = $false foreach($pi in $mi.GetParameters()) { if($comma) { $def += ', ' } $def += (getTypeName $pi.ParameterType) + ' ' + $pi.Name $comma = $true } $def += ')' } Constructor { $type = 'CodeMethod' $def += $tar.Name + '(' $comma = $false foreach($pi in $mi.GetParameters()) { if($comma) { $def += ', ' } else { $comma = $true } $def += (getTypeName $pi.ParameterType) + ' ' + $pi.Name } $def += ')' } Property { $def += (getTypeName $mi.PropertyType) + ' ' + $mi.Name $comma = $true foreach($pi in $mi.GetIndexParameters()) { if($comma) { $def += '('; $type = 'ParameterizedProperty'; $comma = $false } else { $def += ', ' } $def += (getTypeName $pi.ParameterType) + ' ' + $pi.Name } if(-not $comma) { $def += ')' } $def += ' {' if($mi.CanRead) { $def += 'get;' } if($mi.CanWrite) { $def += 'set;' } $def += '}' } Field { $type = 'Properties' $def += (getTypeName $mi.FieldType) + ' ' + $mi.Name } NestedType { $type = 'PropertySet' $def += $tar.FullName + '+' + $mi.Name } } $res += (New-Object Microsoft.Powershell.Commands.MemberDefinition($Target.FullName, $mi.Name, $type, $def)) #if($type -eq 'PropertySet') { $res += (getMembersSub $mi $para $pre) } } return $res } $def = '' if($Static) { $def = 'static ' $ts = 'Static, Public' } else { $ts = 'Instance, Public' } if($Private) { $ts += ', NonPublic' } $res = getMembersSub $Target $ts $def } elseif($Target -ne $null) { $res = (Get-Member -InputObject $Target) } return $res } function kterm { if ($args -eq $null -or $args.length -eq 0) { start powershell } else { start powershell -ArgumentList $args } } function ls { Param( [switch]$l, [switch]$a, [switch]$t, [switch]$la, [switch]$lt ) $cmd = "Get-Childitem " if ($la) { $l = $true $a = $true } if ($lt) { $l = $true $t = $true } if ($args -ne $null -and $args.Length -gt 0) { $cmd += $args + " " } if ($a) { $cmd += "-Force " } if ($t) { $cmd += "| Sort-Object -Property LastWriteTime -Descending " } if($l) { Invoke-Expression $cmd } else { $cs = Invoke-Expression $cmd if($cs -ne [System.Object[]]) { $cs = @($cs) } $len = ($cs | ForEach-Object {if($_ -ne $null -and $_.Name -ne $null) {if($res -lt [Text.Encoding]::Default.GetByteCount($_.Name)){$res=[Text.Encoding]::Default.GetByteCount($_.Name)}}} -Begin {$res=0} -End {$res}) $max = (Get-Host).UI.RawUI.WindowSize.Width if($len -ge $max) { $len = $max - 1 } $max = [math]::Truncate($max / ($len + 1)) $j = 1 for($i = 0; $i -lt $cs.Length; $i++) { $color = "Gray" if($cs[$i] -is [System.IO.DirectoryInfo]) { $color = "Cyan" } if($cs[$i].Extension -match "^.(ps1|lnk|exe)$") { $color = "Green" } if($cs[$i].Extension -match "^.(zip|cab|lzh)$") { $color = "Yellow" } $name = $cs[$i].Name if($j -eq $max) { Write-Host -ForegroundColor $color $name.PadRight($len - [Text.Encoding]::Default.GetByteCount($name) + $name.Length) $j = 1 } elseif($name -ne $null) { Write-Host -NoNewLine -ForegroundColor $color $name.PadRight($len - [Text.Encoding]::Default.GetByteCount($name) + $name.Length + 1) $j++ } } if($j -ne 1) { Write-Host } } } function rm { Param( [switch]$r, [switch]$rf, [switch]$f ) if($rf) { $r = $true $f = $true } if(!$f) { $f = ((Read-Host "$args 削除しますか?(y/N)") -eq 'y') } if($f) { if($r) { Remove-Item -Recurse $args } else { Remove-Item $args } } } function which { for($i = 0; $i -lt $args.length; $i++) { Get-Command $args[$i] | %{ $_.Definition } } } # settings $Env:XYZZYHOME = "D:\tools\editor\xyzzy" $Env:TZ = "JST-9" $rawui = (Get-Host).UI.RawUI $rawuisize = $rawui.BufferSize $rawuisize.Height = 3000 $rawui.BufferSize = $rawuisize $global:EDITOR = "xyzzy" $tooldir = "d:\tools" # alias set-alias -name login -value Start-Host set-alias -name grep -value Select-String set-alias -name gt -value Get-Types set-alias -name xyzzy -value $Env:XYZZYHOME\xyzzycli.exe set-alias -name winmerge -value $tooldir\editor\WinMerge\winmerge set-alias -name uwsc -value $tooldir\utility\uwsc\uwsc Start-Host Export-ModuleMember -Function * -Alias *
環境設定を押し込んでます。
最初のプロセスだけは、「Start-Host("console")」を行う想定です。
logoutモジュール
function Exit-Host() { Param([switch]$Edit) if($Edit) { iex "$EDITOR $env:USERPROFILE\Documents\WindowsPowerShell\Modules\logout\logout.psm1" } else { # proc #read-host "Push Enter key! " if((Get-Host).UI.RawUI.WindowTitle -match '^console(?: .*)?$') { Write-Host "Shutdown process starting." Read-Host "Push Enter key. " shutdown /s /t 3 } else { exit } } } # alias set-alias -name logout -value Exit-Host Export-ModuleMember -Function * -Alias *
「console」のウインドウで「logout」すると、シャットダウンする算段です。
スタートアップ
Start-Host("console")は、スタートアップに登録するショートカットで行います。
ショートカットの内容は「C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "login 'console'"」です。