2

C# で SHExtractIconsW dll 関数を使用する方法、私は AutoIt でこれを行うことができました。

Local $arResult = DllCall('shell32.dll', 'int', 'SHExtractIconsW', _
        'wstr', $sIcon, _
        'int', $aDetails[5], _
        'int', $iSize, _
        'int', $iSize, _
        'ptr*', 0, 'ptr*', 0, 'int', 1, 'int', 0)

これは、マイクロソフトのサイトhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb762163(v=vs.85).aspxからの参照です。

基本的にはexeファイルからアイコンを抽出したいのですが、ここにある例のほとんどはそれができず、autoitではSHExtractIconsWでできるので、C#でやってみたかったのです。

:64x64から256x256までのアイコンサイズが必要です。下ではありません。

4

1 に答える 1

3

これは、文書化されていない関数のようです。

のドキュメントにphIconは次のように書かれています:

この関数が戻ると、アイコン ハンドルの配列へのポインターが含まれます。

ただし、パラメーターには typeHICON*があるため、呼び出し元は配列を提供する必要があります。

のドキュメントpIconIdも間違っています。これも配列であることがわかります。

すべてのマーシャリングは、デフォルト設定を使用して実行できます。この API には ANSI バージョンがないため、完全な名前を付け、を UnicodeSHExtractIconsWに設定します。Charset

ドキュメントに関する限り、呼び出されることについての言及はありませんSetLastError

[DllImport("Shell32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern uint SHExtractIconsW(
    string pszFileName,
    int nIconIndex,
    int cxIcon,
    int cyIcon,
    IntPtr[] phIcon,
    uint[] pIconId,
    uint nIcons,
    uint flags
);

これを呼び出すには、次のように配列を割り当てる必要があります。

IntPtr[] Icons = new IntPtr[nIcons];
uint[] IconIDs = new uint[nIcons];

最後に、@Cody のコメントをエコーし​​ます。この API は明らかに間違って文書化されているため、適切に文書化されていて将来的に信頼できる代替 API を使用しようと思います。


これをすべて機能させるのに苦労しているように見えるので、からアイコンを抽出して表示する楽しいプログラムを次に示しますshell32.dllDestroyIconエラーチェックやアイコンの呼び出しなどは行っていません。

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication12
{
    public partial class Form1 : Form
    {
        [DllImport("Shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        static extern uint SHExtractIconsW(
            string pszFileName,
            int nIconIndex,
            int cxIcon,
            int cyIcon,
            IntPtr[] phIcon,
            uint[] pIconId,
            uint nIcons,
            uint flags
        );

        public Form1()
        {
            InitializeComponent();
        }

        private IntPtr[] Icons;
        private int currentIcon = 0;
        uint iconsExtracted;

        private void Form1_Load(object sender, EventArgs e)
        {
            uint nIcons = 1000;
            Icons = new IntPtr[nIcons];
            uint[] IconIDs = new uint[nIcons];
            iconsExtracted = SHExtractIconsW(
                @"C:\Windows\System32\shell32.dll",
                0,
                256, 256,
                Icons,
                IconIDs,
                nIcons,
                0
            );
            if (iconsExtracted == 0)
                ;//handle error
            Text = string.Format("Icon count: {0:d}", iconsExtracted);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Image = Bitmap.FromHicon(Icons[currentIcon]);
            currentIcon = (currentIcon + 1) % (int)iconsExtracted;
        }
    }
}
于 2013-04-12T20:11:27.727 に答える