P/Invoke

少し調べたので記録。
wikipediaにもあるようにプラットフォーム呼び出し(Platform Invoke)の略。
具体例としては.NETからのWin32APIの呼び出し。(それしか分からないorz)

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace InvokeTest
{
    class ExampleClass
    {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("shell32.dll")]
        static extern int SHGetSpecialFolderPath(IntPtr hwndOwner, StringBuilder lpszPath, int nFolder, int fCreate);

        public void Test(string windowName)
        {
            IntPtr hWnd = FindWindow(null, windowName);
            if (IntPtr.Zero == hWnd)
                Console.WriteLine("Window not found.");
            else
                Console.WriteLine("There is a window named " + windowName + ".");
        }

        public string Test2(int folderCSIDL)
        {
            StringBuilder resultPath = new StringBuilder(255);

            SHGetSpecialFolderPath*1;
            Console.WriteLine("PROGRAM_FILES: " + example.Test2(CSIDL_PROGRAM_FILES));

        }
    }
}

必須はusingでInteropServices?
使いたいapiの宣言の属性でDllImportしてapiの入ったdllを引っ張ればOK。
FindWindow関数は、指定した名前のウィンドウをデスクトップから探す処理。
SHGetSpecialFolderPath関数は、指定したIDの特殊フォルダのファイルパスを取得する。


こんな感じでコンソール出力されます。(新規で「メモ帳」を立ち上げておく必要がある)

There is a window named 無題 - メモ帳.
DESKTOP: C:\Documents and Settings\XXXXXX\デスクトップ
PROGRAM_FILES: C:\Program Files

最初、見つけたサイトページの記述のまま、SHGetSpecialFolderPath関数をcoredll.dllから引っ張ろうとして実行例外を出したのはご愛嬌。(coredll.dllはWindows CEのものらしい。PC環境ではshell32.dll)


特殊フォルダのIDは、多分これ->http://support.microsoft.com/kb/194702/ja
どのapiがどのdllに入っているかはこれ->http://www.pinvoke.net/

*1:IntPtr)0, resultPath, folderCSIDL, 0); return resultPath.ToString(); } } class Program { static void Main(string[] args) { const int CSIDL_DESKTOP = 0x0000; const int CSIDL_PROGRAM_FILES = 0x0026; ExampleClass example = new ExampleClass(); example.Test("無題 - メモ帳"); Console.WriteLine("DESKTOP: " + example.Test2(CSIDL_DESKTOP