« PowerShellでWin32APIを使う。 | トップページ | 標準出力と標準エラーを入れ替えられるか? »

2007年9月 1日 (土)

JScript.NETでWin32APIを使う。

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

import System;
import System.Reflection;
import System.Reflection.Emit;
import System.Runtime;
import System.Text;

// Invoke a Win32 P/Invoke call.
function InvokeWin32(dllName:String, returnType:Type,
  methodName:String, parameterTypes:Type[], parameters:Object[])
{
  // Begin to build the dynamic assembly
  var domain=AppDomain.CurrentDomain;
  var name=new System.Reflection.AssemblyName('PInvokeAssembly');
  var assembly=domain.DefineDynamicAssembly(name,AssemblyBuilderAccess.Run);
  var module=assembly.DefineDynamicModule('PInvokeModule');
  var type=module.DefineType('PInvokeType',TypeAttributes.Public + TypeAttributes.BeforeFieldInit);

  // Define the actual P/Invoke method
  var method=type.DefineMethod(methodName,MethodAttributes.Public+MethodAttributes.HideBySig+MethodAttributes.Static+MethodAttributes.PinvokeImpl,returnType,parameterTypes);

  // Apply the P/Invoke constructor
  var ctor=System.Runtime.InteropServices.DllImportAttribute.GetConstructor([Type.GetType("System.String")]);
  var attr=new System.Reflection.Emit.CustomAttributeBuilder(ctor,[dllName]);
  method.SetCustomAttribute(attr);

  // Create the temporary type, and invoke the method.
  var realType=type.CreateType();
  return realType.InvokeMember(methodName,BindingFlags.Public+BindingFlags.Static+BindingFlags.InvokeMethod,null,null,parameters);
}

function FindWindow(title:String)
{
   var parameterTypes:Type[]=[Type.GetType("System.Int32"),Type.GetType("System.String")];
   var parameters:Object[]=[0,title];

   return InvokeWin32("user32.dll",Type.GetType("System.Int32"),"FindWindow",parameterTypes,parameters);
}

function GetWindowThreadProcessId(hWnd:Int32, ProcessId:Int32[])
{
   var parameterTypes:Type[]=[Type.GetType("System.Int32"),Type.GetType("System.Int32").MakeByRefType()];
   var parameters:Object[]=[hWnd,ProcessId[0]];

   var r=InvokeWin32("user32.dll",Type.GetType("System.Int32"),"GetWindowThreadProcessId",parameterTypes,parameters);
   ProcessId[0]=parameters[1];
   return r;
}

function GetWindowText(hWnd:Int32, lpString:StringBuilder, nMaxCount:Int32)
{
   var parameterTypes:Type[]=[Type.GetType("System.Int32"),Type.GetType("System.Text.StringBuilder"),Type.GetType("System.Int32")];
   var parameters:Object[]=[hWnd,lpString,nMaxCount];

   return InvokeWin32("user32.dll",Type.GetType("System.Int32"),"GetWindowTextA",parameterTypes,parameters);
}

//var hWnd=FindWindow("AAA");
//var hWnd=FindWindow("あああ");
var hWnd=FindWindow(Environment.GetCommandLineArgs()[1]);

Console.WriteLine(hWnd);

var ProcessId:Int32[]=[0];

var ThreadId=GetWindowThreadProcessId(hWnd,ProcessId);

Console.WriteLine(ThreadId);
Console.WriteLine(ProcessId[0]);

var lpString:StringBuilder=new StringBuilder(128);

var nCount=GetWindowText(hWnd,lpString,128);

Console.WriteLine(nCount);
Console.WriteLine(lpString.Length);
Console.WriteLine(lpString);

これを応用すると、スクリプトなどからWin32APIを使うための汎用のCOMオブジェクトが作れますね。

« PowerShellでWin32APIを使う。 | トップページ | 標準出力と標準エラーを入れ替えられるか? »