2022年5月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
無料ブログはココログ

« 2007年7月 | トップページ | 2007年9月 »

2007年8月31日 (金)

PowerShellでWin32APIを使う。

よく分かりませんが、こんな感じで使えるようです。

param([String] $title)

## Invoke a Win32 P/Invoke call.
function Invoke-Win32([string] $dllName, [Type] $returnType, [string] $methodName, 
   [Type[]] $parameterTypes, [Object[]] $parameters)
{
   ## Begin to build the dynamic assembly
   $domain = [AppDomain]::CurrentDomain
   $name = New-Object Reflection.AssemblyName 'PInvokeAssembly'
   $assembly = $domain.DefineDynamicAssembly($name, 'Run')
   $module = $assembly.DefineDynamicModule('PInvokeModule')
   $type = $module.DefineType('PInvokeType', "Public,BeforeFieldInit")

   ## Define the actual P/Invoke method
   $method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl', 
      $returnType, $parameterTypes)

   ## Apply the P/Invoke constructor
   $ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string])
   $attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName
   $method.SetCustomAttribute($attr)

   ## Create the temporary type, and invoke the method.
   $realType = $type.CreateType()
   $realType.InvokeMember($methodName, 'Public,Static,InvokeMethod', $null, $null, 
      $parameters)
}

function FindWindow([String] $WindowName)
{
   $parameterTypes = [Int32], [String]
   $parameters = 0, $WindowName

   Invoke-Win32 "user32.dll" ([Int32]) "FindWindow" $parameterTypes $parameters
}

function GetWindowThreadProcessId([Int32] $hWnd, [ref] $ProcessId)
{
   $parameterTypes = [Int32], [System.Type]::GetType("System.Int32").MakeByRefType()
   $parameters = $hWnd, $ProcessId.Value

   Invoke-Win32 "user32.dll" ([Int32]) "GetWindowThreadProcessId" $parameterTypes $parameters
   $ProcessId.Value=$parameters[1]
}

function GetWindowText([Int32] $hWnd, [Text.StringBuilder] $lpString, [Int32] $nMaxCount)
{
   $parameterTypes = [Int32], [Text.StringBuilder], [Int32]
   $parameters = $hWnd, $lpString, $nMaxCount

   Invoke-Win32 "user32.dll" ([Int32]) "GetWindowTextA" $parameterTypes $parameters
}

$hwnd=FindWindow $title

$ProcessId=0

GetWindowThreadProcessId $hWnd ([ref] $ProcessId)

$ProcessId

$lpString=new-object System.Text.StringBuilder(128)

GetWindowText $hWnd $lpString $lpString.Capacity

$lpString.Length

$lpString.ToString()

Invoke-Win32のオリジナルソースは以下を参照。
From: Lee Holmes
http://www.leeholmes.com/blog/GetTheOwnerOfAProcessInPowerShellPInvokeAndRefOutParameters.aspx

PowerShellでWin32APIが使えるなら、Invoke-Win32をJScript.NETに焼き直して、JScript.NETでも同様にWin32APIが使えますね。

2007年8月30日 (木)

PowerShell.exeでAppActivateする1行バッチファイル

WSHスクリプトは、スクリプトファイルがないと実行できませんが、PowerShellなら、コマンドラインや標準入力にスクリプトが書けます。
PowerShellをWSHスクリプトホストの代わりに使えば、1行バッチやインラインバッチが可能になります。

AppActivate.CMD "ウィンドウタイトル"

PowerShell.exe -command "$wShell=new-object -comobject wscript.shell;$wShell.AppActivate('%*')"

AppActivate.CMDでは、ウィンドウタイトルを""で囲みます。
もし、囲まないと、コンソールウィンドウのタイトルの末尾に付く、
- AppActivate.CMD ウィンドウタイトル
と後方一致するため、自身のコンソールウィンドウを誤爆します。

PowerShell.exeで日本語なども通るSendKeysの1行バッチファイル

.NETで可能なことは、PowerShellでも可能です。
PowerShellで可能なら、1行バッチやインラインバッチでも可能です。

SendKeys.CMD 文字列

PowerShell.exe -command "[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');[Windows.Forms.SendKeys]::SendWait('%*')"

SendKeys.CMD 文字列 では、%や^に、エスケープ^が必要です。
"は、消えて、送られません。

2007年8月27日 (月)

PowerShellスクリプトをWSFファイルにして、ウィンドウ アプリっぽく実行する。

WSHホストには、コンソール バージョンとウィンドウ バージョンがありますが、
PowerShellには、バッチファイルと同じで、コンソール バージョンしかありません。
そこで、以下のように、PowerShellスクリプトをWSFファイルに組み込んで、ウィンドウ アプリっぽく実行します。

<package>
<job>
<script language=vbscript>
Dim wShell
ReDim Args(WScript.Arguments.Count-1)
For k=0 To WScript.Arguments.Count-1
  Args(k)="""" & WScript.Arguments.Item(k) & """"
Next
Set wShell=CreateObject("WScript.Shell")
wShell.Environment("PROCESS").Item("args")=Join(Args,vbTab)
wShell.Environment("PROCESS").Item("arg0")=WScript.ScriptFullName
WScript.Quit CreateObject("WScript.Shell").Run("CScript.exe //job:exec """ & WScript.ScriptFullName & """",7,True)
</script>
</job>
<job id=exec>
<script language=vbscript>
Dim oExec
Dim StdErr
Dim StdOut
Set oExec=CreateObject("WScript.Shell").Exec("powershell.exe -NonInteractive -command ""& {$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,'<![CDATA[')+1)..($s.length-1)]+'';$s='function main {'+[String]::Join([char]13+[char]10,$s)+'}main '+$env:args;invoke-expression $s;}""")
oExec.StdIn.Close
StdErr=oExec.StdErr.ReadAll()
StdOut=oExec.StdOut.ReadAll()
If StdErr<>"" Then MsgBox Join(Array(Args,Empty,StdErr),vbLf),vbCritical,WScript.ScriptName&" - StdErr"
If StdOut<>"" Then MsgBox Join(Array(Args,Empty,StdOut),vbLf),vbInformation,WScript.ScriptName&" - StdOut"
WScript.Quit oExec.ExitCode
</script>
<resource>
<![CDATA[
  $args.gettype()
  $args.length
  $args
#]]></resource></job></package>

これをダブルクリックなどで起動します。ドロップなどで引数も渡せます。
ExecutionPolicyがRestrictedのままでも、実行できます。

上では、最小化(7)にしています。非表示ならRun(,0)に変えてください。

一応、標準出力と標準エラーは、もしあれば、MsgBoxでウィンドウ表示しますが、
量が多いと、Exec()のパイプが詰まってハングアップしたり、
MsgBox()で表示しきれないので、あまり出さないようにしてください。

2007年8月26日 (日)

最小化や非表示で実行されるPowerShellスクリプトファイル(.JS)

PowerShellスクリプトの実行では、コンソールウィンドウが開きます。
そこで、PowerShellスクリプトをJSファイルに組み込んで、
コンソールウィンドウを最小化や非表示にして起動実行します。

PowerShellスクリプトの先頭に4行、末尾に1行を追加して拡張子を.JSにします。

var args=new Array();for(var e=new Enumerator(WScript.Arguments);!e.atEnd();e.moveNext()){args.push('"'+e.item()+'"');}
var wShell=new ActiveXObject('WScript.Shell');var Env=wShell.Environment('PROCESS');Env.Item('args')=args.join('\t');Env.Item('arg0')=WScript.ScriptFullName;
wShell.Run('powershell.exe -command "& {$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,\'/*\')+1)..($s.length-1)]+\'\';$s=\'function main {\'+[String]::Join([char]13+[char]10,$s)+\'}main \'+$env:args;invoke-expression $s;}"',7);
/*
  $args.gettype()
  $args.length
  $args
#*/

これをダブルクリックなどで起動します。ドロップなどで引数も渡せます。
ExecutionPolicyがRestrictedのままでも、実行できます。

上では、最小化(7)にしています。非表示ならRun(,0)に変えてください。

2007年8月25日 (土)

PowerShellの.PS1ファイルを起動するバッチファイル(その5)

更に、標準入力のパイプ、リダイレクションに対応。

PS5.CMD PS1ファイル [引数...] < ファイル

コマンド | PS5.CMD PS1ファイル [引数...]

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(SET args=%*)
(SET args=!args:*%1=!)
(SET arg0=%~f1)
ECHO ON
powershell.exe -command "$stdin=@()+$input;$nl=[char]13+[char]10;if($stdin.length){$stdin=[String]::Join($nl,$stdin)}else{$stdin=[System.Console]::In.ReadToEnd()}$s=cat $env:arg0;$s='function main{'+[String]::Join($nl,$s)+$nl+'}$stdin|main'+$env:args;iex $s"

PowerShellの.PS1ファイルを起動するバッチファイル(その4)

PS1ファイルをインクルードするので、ExecutionPolicyがRestrictedでも実行できます。

PS4.CMD PS1ファイル [引数...]

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(SET args=%*)
(SET args=!args:*%1=!)
(SET arg0=%~f1)
ECHO ON
powershell.exe -command "& {$nl=[char]13+[char]10;$s=cat $env:arg0;$s='function main{'+[String]::Join($nl,$s)+$nl+'}main'+$env:args;iex $s;}"

2007年8月24日 (金)

PowerShell.exeで引数をクリップボードに送る2行バッチファイル

バッチファイルやコマンドプロンプトで、インラインに書くこともできます。

SETCLIP.CMD 引数...

SET args=. getargs %*
PowerShell.exe -command "function getargs{$xargs=$args}iex $env:args;[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');$textbox=new-object System.Windows.Forms.TextBox;$textbox.Multiline=$true;$textbox.Text=[String]::Join([Char]13+[Char]10,$xargs);$textbox.SelectAll();$textbox.Copy()"

PowerShell.exeでクリップボードを標準出力に取り出す1行バッチファイル

バッチファイルやコマンドプロンプトで、インラインに書くこともできます。

CLIPOUT.CMD >ファイル

CLIPOUT.CMD | コマンド

PowerShell.exe -command "[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');$textbox=new-object System.Windows.Forms.TextBox;$textbox.Multiline=$true;$textbox.Paste();write-output $textbox.Text"

PowerShell.exeで標準入力をクリップボードに送る1行バッチファイル

バッチファイルやコマンドプロンプトで、インラインに書くこともできます。

CLIP.CMD
ほにゃらら
へにゃらら
ふにゃらら
^Z

CLIP.CMD <ファイル

コマンド | CLIP.CMD

PowerShell.exe -command "$stdin=@()+$input;if($stdin.length){$stdin=[String]::Join([Char]13+[Char]10,$stdin)}else{$stdin=[System.Console]::In.ReadToEnd()}[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');$textbox=new-object System.Windows.Forms.TextBox;$textbox.Multiline=$true;$textbox.Text=$stdin;$textbox.SelectAll();$textbox.Copy()"

PowerShellで標準入力をクリップボードに送るclip.ps1

clip.ps1
ほにゃらら
へにゃらら
ふにゃらら
^Z

clip.ps1 <ファイル

コマンド | clip.ps1

$stdin=@()+$input
if($stdin.length){
  $stdin=[String]::Join("`r`n",$stdin)
}else{
  $stdin=[System.Console]::In.ReadToEnd()
}
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$textbox = new-object System.Windows.Forms.TextBox
$textbox.Multiline = $true
$textbox.Text = $stdin
$textbox.SelectAll()
$textbox.Copy()

2007年8月23日 (木)

標準出力と標準エラーを別々にパイプに渡す。

標準出力と標準エラーを別々にファイルに出すには、

hoge >標準出力 2>標準エラー

標準出力と標準エラーを一緒にパイプに渡すには、

hoge 2>&1 |パイプ

ここまでは、普通。

では、標準出力と標準エラーを別々にパイプに渡すには?

無理?

いえいえ、

(hoge.cmd | clip.exe) 2>&1 | messagebox.exe

と書けば、hoge.cmdの標準出力はクリップボードに送られて、
標準エラーがメッセージボックスに出ます。

バッチファイルの引数にパイプやリダイレクションが書ける。

VBやVBAのShell()、WScript.ShellのExec()、「ファイル名を指定して実行」、関連付け、タスクスケジューラに、バッチファイルが直接書けるのですね。CMD.EXE /Cなしに。

更に、そのバッチファイルの引数にパイプやリダイレクションが書けますね。

例えば、「ファイル名を指定して実行」に、

hoge.cmd | messagebox.exe

と書けば、hoge.cmdの標準出力がメッセージボックスに出るし、

hoge.cmd 2>&1 | messagebox.exe

と書けば、hoge.cmdの標準出力と標準エラーの両方がメッセージボックスに出ます。

また、コンソールウィンドウが閉じるのを止めるには、

hoge.cmd & PAUSE

続けて、コンソールを使いたければ、

hoge.cmd & CMD

パイプ前後の複文で、行末に余計な空白が付くトラブルを防止する。

パイプ前後の複文でも、同様のトラブルが発生します。

(
SET A=aaa
CALL ECHO="%%A%%"
)|MORE

しかし、これには、前述の対策は効きません。
最初から空白を付けて、参照時に除去するか、

(
SET A=aaa
CALL ECHO="%%A:~0,-1%%"
)|MORE

CMD /Cで、明示的に、実行するか。

CMD /C,SET A=aaa^&CALL ECHO="%%%%A%%%%"|MORE

Webページ上でバッチファイルの行末に余計な空白が付くのを防止する。

バッチファイルを掲示板などに書き込むと、行末に空白が余分に付いて、そのまま利用すると誤動作します。

例えば、以下を取り出して実行すると、空白が余分に付きます。
SET A=aaa
ECHO="%A%"

こういうときは、以下のようにするとよいでしょう。
(SET A=aaa)
(ECHO="%A%")

過去記事で、バッチファイルを利用する際は、行末の空白に注意し、削除してからご利用ください。

2007年8月22日 (水)

PowerShellの.PS1ファイルをバッチファイル化する。(その4)

更に、標準入力が使えるようにします。

.PS1ファイルの先頭に6行を加えて、拡張子を.CMDに変えます。

@ECHO OFF
SETLOCAL
(SET args=%*)
(SET arg0=%~f0)
powershell.exe -command "$stdin=@()+$input;if($stdin.length){$stdin=[String]::Join([Char]13+[Char]10,$stdin)}else{$stdin=[System.Console]::In.ReadToEnd()}$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,'GOTO:EOF')+1)..($s.length-1)];$s='function getargs{$xargs=$args}. getargs '+$env:args+';'+[String]::Join([char]13+[char]10,$s);invoke-expression $s;"
GOTO:EOF
  $xargs.gettype()
  $xargs.length
  $xargs
  $stdin

引数は、環境変数args経由、$xargsに取り出しています。
元のスクリプトは、$xargsを参照するように変えます。
標準入力は$stdinで参照するように変えます。

或いは、.PS1ファイルの先頭に6行を加えて、拡張子を.CMDに変えます。

@ECHO OFF
SETLOCAL
(SET args=%*)
(SET arg0=%~f0)
powershell.exe -command "$stdin=@()+$input;if($stdin.length){$stdin=[String]::Join([Char]13+[Char]10,$stdin)}else{$stdin=[System.Console]::In.ReadToEnd()}$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,'GOTO:EOF')+1)..($s.length-1)]+'';$s='function main {'+[String]::Join([char]13+[char]10,$s)+'}$stdin|main '+$env:args;invoke-expression $s;"
GOTO:EOF
  $args.gettype()
  $args.length
  $args
  $input

これは、元のスクリプトを関数に括って呼び出すので、引数を$argsのまま参照できます。
標準入力は$inputのまま参照できます。

2007年8月21日 (火)

PowerShellの.PS1ファイルをバッチファイル化する。(その3)

スクリプトを標準入力から渡すと、うまく行かないことがあるので、代わりに、スクリプトをファイルから読んで実行します。

.PS1ファイルの先頭に6行を加えて、拡張子を.CMDに変えます。
※ 末尾の空行追加は不要です。

@ECHO OFF
SETLOCAL
(SET args=%*)
(SET arg0=%~f0)
powershell.exe -command "& {$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,'GOTO:EOF')+1)..($s.length-1)];$s='function getargs{$xargs=$args}. getargs '+$env:args+';'+[String]::Join([char]13+[char]10,$s);invoke-expression $s;}"
GOTO:EOF
  $xargs.gettype()
  $xargs.length
  foreach($arg in $xargs){$arg}

引数は、環境変数args経由、$xargsに取り出しています。
元のスクリプトは、$xargsを参照するように変えます。

或いは、.PS1ファイルの先頭に6行を加えて、拡張子を.CMDに変えます。

@ECHO OFF
SETLOCAL
(SET args=%*)
(SET arg0=%~f0)
powershell.exe -command "& {$s=get-content $env:arg0;$s=$s[([Array]::LastIndexOf($s,'GOTO:EOF')+1)..($s.length-1)]+\'\';$s='function main {'+[String]::Join([char]13+[char]10,$s)+'}main '+$env:args;invoke-expression $s;}"
GOTO:EOF
  $args.gettype()
  $args.length
  foreach($arg in $args){$arg}

これは、元のスクリプトを関数に括って呼び出すので、引数を$argsのまま参照できます。

PowerShellでソースファイルをインクルードする。

PowerShellには.(dot)sourceという機能がありますが、これは違います。
.(dot)sourceはスコープの扱いが異なるだけで、invoke-itemと同じです。
例えば、
. hoge.txt
とやると、メモ帳が立ち上がります。

unix shellの.コマンドや、Cの#include、WSFなどの<script src= >などのように、
単純にソースファイルをインクルードするにはどうするか。

.\include.ps1 ファイル...

invoke-expression ([String]::Join("`r`n",$(get-content $args)))

現スコープにインクルードするなら、.(dot)sourceを使って、
. .\include.ps1 ファイル...

2007年8月20日 (月)

PowerShellの.PS1ファイルをバッチファイル化する。(その2)

(その1)では、引数が渡りません。そこで、引数を、環境変数経由で渡します。

.PS1ファイルの先頭に3行、末尾に空行を加えて、拡張子を.CMDに変えます。

@SET args=%* & MORE +1 %0 | powershell.exe -command - & GOTO:EOF
function getargs {$xargs=$args}
iex ". getargs $env:args"
    $xargs.gettype()
    $xargs.length
    foreach($arg in $xargs){$arg}
(空行)

この例では、環境変数argsを$xargsに取り出します。
元のスクリプトは、$argsの代わりに$xargsを参照するように変えます。

或いは、元のスクリプトを関数に括って呼び出せば、引数を$argsのまま参照できます。

.PS1ファイルの先頭に2行、末尾に2行を加えて、拡張子を.CMDに変えます。

@SET args=%* & MORE +1 %0 | powershell.exe -command - & GOTO:EOF
function main {
    $args.gettype()
    $args.length
    foreach($arg in $args){$arg}
} iex "main $env:args"
(空行)

PowerShellの.PS1ファイルをバッチファイル化する。(その1)

PowerShellの.PS1ファイルをそのまま他人に渡しても、それを実行するには、いろいろと設定が必要で、困ります。
そんなときは、.PS1ファイルをバッチファイルにラップするとよいでしょう。
これなら、ExecutionPolicyがRestrictedのままでも、実行できます。

.PS1ファイルの先頭に1行、末尾に空行を加えて、拡張子を.CMDに変えます。

@MORE +1 %0 | powershell.exe -command - & GOTO:EOF
if(1){
  write-output hoge
}
(空行)

この例で、もし、空行がないと、write-output hogeが実行されません。

標準入力からのコマンドの読み込み/解釈/実行の単位は、「単行モード」と「継続行モード」の二つがあります。
一行読んで、もし、一行で完結してないときは、「継続行モード」に切り替わり、それが空行まで続きます。

大概は、空行の追加でうまく行きますが、以下のような、一見、一行で完結してそうな紛らわしい記述があると駄目です。:-(
if(){~}
else{~}

PowerShellで、列挙子(Enumerator)を配列(Array)に戻す。

列挙子(Enumerator)を配列(Array)に戻すにはどうするか?

複数行のテキストをパイプに渡して、受け取った側で、元の複数行テキストに戻すとき、
配列なら、[String]::Join("`r`n",配列)で簡単に複数行テキストにできますが、
$inputは列挙子なので、単純にStringに型変換すると、[String]::Join(" ",配列)相当になってしまいます。

地道に、

$stdin=@()
$input|foreach{$stdin+=$_}

$stdin=@()
foreach($x in $input){$stdin+=$x}

などとすればよいのですが、何とか一発で、出来ないものでしょうか?

$stdin=@()+$input

でよいようです。

2007年8月19日 (日)

PowerShellの.PS1ファイルの関連付け(その5)

(その4)は、コンソールの標準入力が取れますが、パイプやリダイレクションが駄目。
そこで、今度こそ究極の関連付けです。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1]
"EditFlags"=dword:00020000

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
@="%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe,0"

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
@="CMD.EXE /S /V:ON /K \"SET ARGS=\"%1\" %*&powershell.exe -command \"$input | & !ARGS:\"='!\"\""

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\ShellEx]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\ShellEx\DropHandler]
@="{60254CA5-953B-11CF-8C96-00AA00B8708C}"

処理結果が確認できるようPowerShellウィンドウを開いたままにしてます。
閉じるなら、/Kを/Cに変えます。

ただし、関連付けの変更だけでは駄目です。

Windows 2000/XPの初期バージョンには、以下の障害があります。

関連付けによるコンソールアプリの起動では、
標準出力のバイプ、リダイレクションやコンソールからの標準入力はOK。
標準入力のパイプやリダイレクションがエラー「ハンドルが無効です」になります。

詳細は以下を参照。
http://support.microsoft.com/kb/321788/
STDIN-STDOUT リダイレクトは、ファイルの関連付けから起動すると動作しないことがある

関連付けでなく、powershell.exeを明示的に起動すれば、パイプ入力やリダイレクション入力も可能です。
それが、前述のPS.CMDです。

また、修正済みバージョンでも、そのままでは、使えません。
以下の.REGファイルをレジストリに結合して、ポリシーを変更する必要があります。
変更後、システムの再起動が必要です。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer]
"InheritConsoleHandles"=dword:00000001

PowerShellの.PS1ファイルを起動するバッチファイル(その3)

標準入力のパイプ、リダイレクションに対応。

PS3.CMD PS1ファイル [引数...] < ファイル

コマンド | PS3.CMD PS1ファイル [引数...]

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET ARGS=%*
SET ARG1=%~1
IF "%ARG1:\=%"=="%ARG1%" SET ARGS=!ARGS:*%1="%~f1"!
ECHO ON
PowerShell.exe -command "$input | & %ARGS:"='%"

バッチファイルは、後述の関連付けやポリシーの変更をしなくても使えます。:-)

PowerShellで、標準入力をMessageBoxに出すMessageBox.PS1を作る。(その3)

(その1)と(その2)は、相互補完関係にあるため、両方の技を合わせます。
これで、標準入力がコンソール、パイプ、リダイレクションのすべての場合に対応します。

MessageBox.PS1

$stdin=@()
$input|foreach{$stdin+=$_}
if($stdin.length){
  $stdin=[String]::Join("`r`n",$stdin)
}else{
  $stdin=[System.Console]::In.ReadToEnd()
}
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show($stdin)

2007年8月18日 (土)

PowerShellで、標準入力をMessageBoxに出すMessageBox.PS1を作る。(その2)

では、$inputを使うとどうでしょう?

MessageBox.PS1

$a=@()
$input|foreach{$a+=$_}
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show([String]::Join("`r`n",$a))

こうすると、(その1)で駄目だった以下が可能になります。

CMD.EXE
powershell.exe
type hoge.txt | .\MessageBox.PS1
※ PowerShellは、< を未サポート。パイプで代替する。

CMD.EXE
powershell.exe
dir | .\MessageBox.PS1
※ PowerShell内のパイプは、[System.Console]::Inで読めない。$inputで読む。

CMD.EXE
powershell.exe -command "$input | .\MessageBox.PS1" < hoge.txt
※ -commandは、PowerShell内のパイプと同じ。$inputで読む。

CMD.EXE
dir | powershell.exe -command "$input | .\MessageBox.PS1"
※ 同じ。

CMD.EXE
dir | PS.CMD MessageBox.PS1
※ 関連付けの問題。ここではPS.CMDを使用。

CMD.EXE
PS.CMD MessageBox.PS1 < hoge.txt
※ 同じ。

ただし、(その1)のシンタクスとの違いに注意。

ここで新出のPS.CMDは後述します。また、関連付けも、後述します。

逆に、(その1)で出来たことが(その2)では出来ません。:-(

2007年8月17日 (金)

PowerShellで、標準入力をMessageBoxに出すMessageBox.PS1を作る。(その1)

今度は、PowerShellで、標準入力をMessageBoxに出すMessageBox.PS1を作ります。

先のJScript.NETソースをPowerShellスクリプトに焼き直します。

MessageBox.js

import System.Windows.Forms;
System.Windows.Forms.MessageBox.Show(System.Console.In.ReadToEnd());

MessageBox.PS1

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show([System.Console]::In.ReadToEnd())

以下の使い方ができます。

CMD.EXE
powershell.exe
.\MessageBox.PS1
ほにゃらら
へにゃらら
ふにゃらら
^Z

CMD.EXE
MessageBox.PS1
ほにゃらら
へにゃらら
ふにゃらら
^Z
※ 関連付け(その4)を使用。

CMD.EXE
powershell.exe < hoge.txt
.\MessageBox.PS1

CMD.EXE
dir | powershell.exe
.\MessageBox.PS1

しかし、以下は駄目です。

CMD.EXE
powershell.exe
.\MessageBox.PS1 < hoge.txt
※ PowerShellは、< を未サポート。パイプで代替する。

CMD.EXE
powershell.exe
dir | .\MessageBox.PS1
※ PowerShell内のパイプは、[System.Console]::Inで読めない。$inputで読む。

CMD.EXE
powershell.exe -command .\MessageBox.PS1 < hoge.txt
※ -commandは、PowerShell内のパイプと同じ。

CMD.EXE
dir | powershell.exe -command .\MessageBox.PS1
※ 同じ。

CMD.EXE
dir | MessageBox.PS1
※ 関連付けの問題。

CMD.EXE
MessageBox.PS1 < hoge.txt
※ 同じ。

2007年8月16日 (木)

標準入力をMessageBoxに出すMessageBox.exeを.NETで作る。

何それ? 標準入力をMessageBoxに出すコマンドです。
タイトルだの、ボタンだの、と欲張らなければ、JScript.NETで簡単に作れます。

MessageBox.js

import System.Windows.Forms;
MessageBox.Show(System.Console.In.ReadToEnd());

これを以下でコンパイルします。
jsc.exe MessageBox.js

使用法は、

dir | MessageBox

MessageBox < hoge.txt

MessageBox
ほにゃらら
へにゃらら
ふにゃらら
^Z

2007年8月15日 (水)

標準入力をクリップボードに送るclip.exeを.NETで作る。

clip.exeは、Windows 2003 Serverには入ってますが、XPなどに標準では入ってません。
純正のclip.exeをWindows 98 Resource Kit からダウンロードすることも出来ますが、簡単なのでJScript.NETで作っちゃいましょう。

clip.js

import System.Windows.Forms;
Clipboard.SetDataObject(System.Console.In.ReadToEnd(),true);

これを以下でコンパイルします。
jsc.exe clip.js

使用法は、

dir | clip

clip < hoge.txt

clip
ほにゃらら
へにゃらら
ふにゃらら
^Z

2007年8月14日 (火)

WinDiff.exeは「送る」で使う。

WinDiff.exeを「送る」に登録しておき、エクスプローラで、
ファイル2つ、または、フォルダ2つを選択して送れば、簡単です。

これが、もし、異なるフォルダの2ファイル/フォルダのときは?

以下のパッケージのWinDiffWithClipArg.VBSを「送る」に登録しておき、
エクスプローラで、一つ目を「コピー」、二つ目を「送る」。

WinDiffWithArg.VBS
異なるフォルダの2ファイル/フォルダをWinDiff.EXEに与えるVBScript
http://www.vector.co.jp/soft/winnt/prog/se397594.html

WinDiff.exeをテキスト閲覧に使う。

ファイル1つ、または、フォルダ1つを開けば、テキスト閲覧に使えます。
行番号も表示されて便利です。

WinDiff.exeのショートカットをSendToに入れておくとよいでしょう。

このとき、作業フォルダを空のフォルダに設定しておきます。
引数が1つのとき、2つ目のデフォルトが作業フォルダなので。

ところで、Windows XPのSupport ToolsのWinDiff.exeには、障害があって、
Expand画面の下部に、Outline画面が消えずに、映り込みます。
これは致命的に使いにくいので、Visual Studioか、Platform SDKなど、
他の版を探して使ってください。

2007年8月13日 (月)

「検索」「ファイルやフォルダ」を開いて検索条件をセットする。(その3)

「検索」「ファイルやフォルダ」を開いて検索条件をセットする。(その3)

PowerShellでなら。

$L="C:\Documents and Settings\Default User\デスクトップ"
$O="*.txt"
$W="日本語"
$wShell=new-object -com WScript.Shell
$Shell=new-object -com Shell.Application
$Shell.FindFiles()
while(!$wShell.AppActivate("検索結果")){
  sleep -m 100
}
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[Windows.Forms.SendKeys]::SendWait("%l%l$L%o$O%w$W")

同様です。

「検索」「ファイルやフォルダ」を開いて検索条件をセットする。(その2)

日本語が通るウィンドウ アプリ版のSendKeys.exeを使えば。

L="C:\Documents and Settings\Default User\デスクトップ"
O="*.txt"
W="日本語"
Set wShell=CreateObject("WScript.Shell")
Set Shell=CreateObject("Shell.Application")
Shell.FindFiles
Do While Not wShell.AppActivate("検索結果")
  WScript.Sleep 100
Loop
wShell.Run "SendKeys.exe %l%l" & L & "%o" & O & "%w" & W

クリップボードを貼り付けるより単純です。

検索を開始するなら、最後に%r。

「検索」「ファイルやフォルダ」を開いて検索条件をセットする。

固定の条件なら、「条件条件を保存(A)」で.FNDファイルを作ればよいのですが、
可変の条件の場合は、どうするか?

クリップボードに入れて、WScript.ShellのSendKeys("^v")で貼り付ける?

L="C:\Documents and Settings\Default User\デスクトップ"
O="*.txt"
W="日本語"
Set wShell=CreateObject("WScript.Shell")
Set Shell=CreateObject("Shell.Application")
Shell.FindFiles
Do While Not wShell.AppActivate("検索結果")
  WScript.Sleep 100
Loop
Set uf=CreateObject("Forms.Form.1")
Set tb=uf.Controls.Add("Forms.TextBox.1").Object
tb.MultiLine=True
PutText L
WScript.Sleep 100
wShell.SendKeys "%l%l^v"
WScript.Sleep 100
PutText O
WScript.Sleep 100
wShell.SendKeys "%o^v"
WScript.Sleep 100
PutText W
WScript.Sleep 100
wShell.SendKeys "%w^v"

Sub PutText(Text)
tb.Text=Text
tb.SelStart=0
tb.SelLength=tb.TextLength
tb.Copy
End Sub

貼り付け箇所が複数なので、タイミングが微妙です。

2007年8月12日 (日)

最小化や非表示で起動できるPowerShellスクリプトファイル(.PS1)

タスクスケジューラ、ATコマンド、スタートアップ、ショートカットなどから、
PowerShellスクリプトファイルを最小化や非表示で起動できます。

PS1ファイルの先頭と末尾に各1行を書き加えます。

#@~^AQAAAA==~IAAAAA==^#~@ new ActiveXObject('WScript.Shell').Run('powershell.exe -command & \''+WScript.ScriptFullName+'\'',7); /*
write-output "aaa"
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show('aaaaaaaaaa')
#*/

これを、
wscript.exe //e:jscript.encode PS1ファイル
で、起動します。

上では、引数を渡してませんが、渡すこともできます。

#@~^AQAAAA==~IAAAAA==^#~@ var args=new Array();for(var e=new Enumerator(WScript.Arguments);!e.atEnd();e.moveNext()){
#@~^AQAAAA==~IAAAAA==^#~@ var arg=e.item();if(arg.indexOf(' ')+1)args.push('\''+arg+'\'');else args.push(arg);}
#@~^AQAAAA==~IAAAAA==^#~@ new ActiveXObject('WScript.Shell').Run('powershell.exe -command & \''+WScript.ScriptFullName+'\' '+args.join(' '),7); /*
write-output $args
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show([String]::Join("`n",$args))
#*/

wscript.exe //e:jscript.encode PS1ファイル 引数...

2007年8月11日 (土)

最小化や非表示で実行されるPowerShellスクリプトファイル(.JSE)

PowerShellスクリプトの前に1行、後に2行を追加して拡張子を.JSEにします。
これをダブルクリックなどで起動します。

#@~^AQAAAA==~IAAAAA==^#~@ new ActiveXObject('WScript.Shell').Run('CMD.EXE /K,powershell.exe -command - <"'+WScript.ScriptFullName+'"',7); /*
write-output "aaa"
(空行)
#*/

上では、最小化(7)で、終了時にコンソールを閉じる(/C)、にしています。

都合により引数は渡せません。

[参考]
# PowerShellのコメント
/* JScriptのコメント */
#@~^AQAAAA==~IAAAAA==^#~@ JScript.Encodeの空白

2007年8月10日 (金)

PowerShellの.PS1ファイルの関連付け(その4)

その3は、標準入力が取れません。
再度、究極の関連付けです。一行バッチを関連付けに組み込みます。
これでドロップも標準入力もうまく行きます。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1]
"EditFlags"=dword:00020000

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
@="%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe,0"

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
@="CMD.EXE /S /V:ON /K \"SET ARGS=\"%1\" %*&powershell.exe -command ^& !ARGS:\"='!\""

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\ShellEx]

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\ShellEx\DropHandler]
@="{60254CA5-953B-11CF-8C96-00AA00B8708C}"

処理結果が確認できるようPowerShellウィンドウを開いたままにしてます。
閉じるなら、/Kを/Cに変えます。

2007年8月 9日 (木)

PowerShellで、自分のコンソールウィンドウを最小化、最大化、元に戻す。

PowerShellで、Win32APIのSendMessage()を使う方法もありますが、ここでは、Win32APIを使わない方法で。

$process=[System.Diagnostics.Process]::GetCurrentProcess()
$hwnd=$process.MainWindowHandle
if($hwnd -eq 0){
  $title=$Host.UI.RawUI.WindowTitle
  $Host.UI.RawUI.WindowTitle+=(new-object random).next()
  $process=ps|where {$_.MainWindowTitle -eq $Host.UI.RawUI.WindowTitle}
  $Host.UI.RawUI.WindowTitle=$title
  $hwnd=$process.MainWindowHandle
}
$WM_SYSCOMMAND=274
$SC_MINIMIZE=61472
$SC_MAXIMIZE=61488
$SC_RESTORE=61728
if($hwnd){
  [void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
  $message=[System.Windows.Forms.Message]::Create($hwnd,$WM_SYSCOMMAND,$SC_MINIMIZE,0)
  $nativeWindow=new-object System.Windows.Forms.NativeWindow
  $nativeWindow.DefWndProc([ref]$message)
  $nativeWindow=$null
}

これで、一応、動きますが、これで良いのか、悪いのか。。。

2007年8月 8日 (水)

スクリプトからコンソールウィンドウの「すべて選択」「コピー」「貼り付け」

コンソールウィンドウの編集メニューをスクリプトから操作するには?

コンソールウィンドウに、SendKeys "Alt+ "しても効きません。

そこで、Excelを使って、Win32APIのSendMessageを呼び出します。

ConsoleCopy.VBS [ウィンドウタイトル]

ウィンドウタイトルで指定したコンソールウィンドウで、
「すべて選択」してクリップボードに「コピー」します。

Set Application=CreateObject("Excel.Application")
If WScript.Arguments.Count() Then
  Title=WScript.Arguments.Item(0)
End If
Do
  If Title<>"" Then
    hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JCC"",""ConsoleWindowClass"","""&Title&""")")
  Else
    hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JCJ"",""ConsoleWindowClass"",0)")
  End If
  If hwnd Then
    Application.ExecuteExcel4Macro( "CALL(""user32"",""SendMessageA"",""JJJJJ""," & hwnd & ",273,65525,0)")
    Application.ExecuteExcel4Macro( "CALL(""user32"",""SendMessageA"",""JJJJJ""," & hwnd & ",273,65520,0)")
    Exit Do
  End If
  Title=InputBox("ウィンドウが見つかりません。",WScript.ScriptName,Title)
Loop Until IsEmpty(Title)

ConsolePaste.VBS [ウィンドウタイトル]

ウィンドウタイトルで指定したコンソールウィンドウに、
クリップボードから「貼り付け」ます。

ウィンドウタイトルを省略すると、最初に見つかったコンソールウィンドウを
操作します。

コンソールウィンドウが見つからない場合、ウィンドウタイトルを
プロンプトします。

Set Application=CreateObject("Excel.Application")
If WScript.Arguments.Count() Then
  Title=WScript.Arguments.Item(0)
End If
Do
  If Title<>"" Then
    hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JCC"",""ConsoleWindowClass"","""&Title&""")")
  Else
    hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JCJ"",""ConsoleWindowClass"",0)")
  End If
  If hwnd Then
    Application.ExecuteExcel4Macro( "CALL(""user32"",""SendMessageA"",""JJJJJ""," & hwnd & ",273,65521,0)")
    Exit Do
  End If
  Title=InputBox("ウィンドウが見つかりません。",WScript.ScriptName,Title)
Loop Until IsEmpty(Title)

2007年8月 7日 (火)

スクリプトでクリックボードを使う。

定番のIEは、out process serverなので、重い。
ExcelやWordなどOffice製品が入っていれば、MSFromsが使えます。
こちらは、in process serverなので軽い。

Sub PutText(Text)
Dim uf
Dim tb
Set uf=CreateObject("Forms.Form.1")
Set tb=uf.Controls.Add("Forms.TextBox.1").Object
tb.MultiLine=True
tb.Text=Text
tb.SelStart=0
tb.SelLength=tb.TextLength
tb.Copy
Set tb=Nothing
Set uf=Nothing
End Sub

Function GetText()
Dim uf
Dim tb
Set uf=CreateObject("Forms.Form.1")
Set tb=uf.Controls.Add("Forms.TextBox.1").Object
tb.MultiLine=True
If tb.CanPaste Then tb.Paste
GetText=tb.Text
Set tb=Nothing
Set uf=Nothing
End Function

2007年8月 6日 (月)

クリップボードをクリアする。

テキストボックスでは、コピー、貼り付けは出来ますが、クリップボードのクリアが出来ません。

そこで、

MSHTA.EXE "javascript:close(clipboardData.clearData())"

または、

MSHTA.EXE vbscript:Execute("clipboardData.clearData:close:")

※ クリップブックで見ると、なぜか、
「現在の形式の情報はクリップブックでは表示されません。
情報を表示するには、ドキュメントに入りつけてください。」
となって、クリップブックで削除した場合とは表示が異なります。

2007年8月 5日 (日)

PowerShellでクリップボードを使う。

System.Windows.Forms.TextBoxを使います。

PowerShellからクリップボードにテキストを送る。

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$textbox = new-object System.Windows.Forms.TextBox
$textbox.Multiline = $true
$textbox.Text = "あいうえお"
$textbox.SelectAll()
$textbox.Copy()

ここで、
$textbox.Text = [string]::join("`r`n", $args)
に変えて、PS1ファイルにファイルをドロップすれば、
ドロップしたファイルのパス名のリストをクリップボードに送ります。

クリップボードからテキストを取り出す。

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$textbox = new-object System.Windows.Forms.TextBox
$textbox.Multiline = $true
$textbox.Paste()
write-output $textbox.Text

2007年8月 4日 (土)

Doskeyのコマンド履歴にコマンドラインを事前設定する(その2)

コマンドを実行しないで、事前にDoskeyのコマンド履歴にコマンドラインを事前設定することが出来るか?

もし、それが出来れば、最初からコマンド履歴の編集機能が使えて便利です。

そこで、以下のようなバッチファイルを作って実行します。

@ECHO OFF
REM SendKeys.exe %{f7}
SendKeys.exe if 1==2 {(}^^m
SendKeys.exe あああああ^^m
SendKeys.exe いいいいい^^m
SendKeys.exe ううううう^^m
SendKeys.exe {)}^^m
SendKeys.exe {f7}

コンソールアプリ版の日本語が通るSendKeys.exeを使用します。
これをPATHに入れておくか、そのフルパス名を指定します。

Alt+F7キーで履歴を消去します。

コマンドプロンプトで、
if 1==2 (
)
の間が実行されないことを利用します。

^mは、CRです。^はエスケープ^が必要。
ENTERキーは、誤爆時に危険なので使わないほうがよいでしょう。

F7キーで履歴をダイアログ表示します。

2007年8月 3日 (金)

バッチ、VBS、コンソールアプリの起動時にコマンドラインを編集する。

バッチファイル、VBSファイル、コンソールアプリなどを、
ダブルクリックや右クリックのコンテキストメニューから起動すると、
起動時に引数を与えられなかったり、
終了時にコンソールウィンドウが閉じて結果が見れなかったりして、
ほとんど役立たずです。

そこで、以下の.REGファイルを結合すると、
batfile/cmdfile/exefile/vbsfileに、
「コマンド プロンプトで開く(K)」で
「CMD.EXE /K,SendKeys.exe "%1" %*」などを関連付けます。

これにより、
起動時にコマンドラインを編集して引数を書き換えることができます。
終了時にコンソールウィンドウが開いたままで結果を見ることができます。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\batfile\shell\Open2]
@="コマンド プロンプトで開く(&K)"

[HKEY_CLASSES_ROOT\batfile\shell\Open2\Command]
@="CMD.EXE /K,SendKeys.exe \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\shell\Open2]
@="コマンド プロンプトで開く(&K)"

[HKEY_CLASSES_ROOT\cmdfile\shell\Open2\Command]
@="CMD.EXE /K,SendKeys.exe \"%1\" %*"

[HKEY_CLASSES_ROOT\exefile\shell\Open2]
@="コマンド プロンプトで開く(&K)"

[HKEY_CLASSES_ROOT\exefile\shell\Open2\Command]
@="CMD.EXE /K,SendKeys.exe \"%1\" %*"

[HKEY_CLASSES_ROOT\vbsfile\shell\Open3]
@="コマンド プロンプトで開く(&K)"

[HKEY_CLASSES_ROOT\vbsfile\shell\Open3\Command]
@="CMD.EXE /K,SendKeys.exe CScript.exe \"%1\" %*"

コンソールアプリ版のSendKeys.exeを使用します。
SendKeys.exeをPATHに入れておくか、フルパスを指定します。

2007年8月 2日 (木)

日本語なども通るSendKeys.exeを作る。

WScript.ShellやVBAのSendKeys()では、日本語やPrintScreenキーを送ることができません。

しかし、VBのSendKeys()や.NETのSystem.Windows.Forms.SendKeys.SendWait()では、可能です。

そこで、.NETで日本語なども通るSendKeys.exeを作っておくと、便利です。

SendKeys.JS

import System;
import System.Windows.Forms;
var CommandLine:String=Environment.CommandLine;
if(CommandLine.StartsWith('"')){
  CommandLine=CommandLine.Substring(CommandLine.IndexOf('"',1)+2);
}else{
  CommandLine=CommandLine.Substring(CommandLine.IndexOf(' ')+1);
}
try{
  SendKeys.SendWait(CommandLine);
}catch(e){
  Console.Error.WriteLine(CommandLine);
  Console.Error.WriteLine(e.ToString());
}

これをコンソール アプリにコンパイルします。

jsc SendKeys.JS

また、ウィンドウ アプリ版も同様に作っておくとよいでしょう。

WSendKeys.JS

import System;
import System.Windows.Forms;
var CommandLine:String=Environment.CommandLine;
if(CommandLine.StartsWith('"')){
  CommandLine=CommandLine.Substring(CommandLine.IndexOf('"',1)+2);
}else{
  CommandLine=CommandLine.Substring(CommandLine.IndexOf(' ')+1);
}
Console.WriteLine(CommandLine);
try{
  SendKeys.SendWait(CommandLine);
}catch(e){
  MessageBox.Show(CommandLine + '\n\n' + e.ToString(),Environment.GetCommandLineArgs()[0],MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
}

ウィンドウ アプリにコンパイルします。

jsc /t:winexe WSendKeys.JS

2007年8月 1日 (水)

画面全体やアクティブウィンドウのスナップショットを取得する。(その2)

WScript.ShellやVBAのSendKeys()では、日本語やPrintScreenキーを送ることができません。

しかし、VBのSendKeys()や.NETのSystem.Windows.Forms.SendKeys.SendWait()では、可能です。

こういうときは、JScript.NETでexeを作っちゃいましょう。とても簡単です。

アクティブウィンドウのスナップショットを取得します。

import System.Windows.Forms;
System.Windows.Forms.SendKeys.SendWait('{PRTSC}');

または、

import System.Windows.Forms;
System.Windows.Forms.SendKeys.SendWait('%{PRTSC}');

画面全体のスナップショットを取得します。

import System.Windows.Forms;
System.Windows.Forms.SendKeys.SendWait('+{PRTSC}');

または、

import System.Windows.Forms;
System.Windows.Forms.SendKeys.SendWait('^{PRTSC}');

jsc /t:winexe ~.JS
で、コンパイルします。

« 2007年7月 | トップページ | 2007年9月 »