بحاجة إلى مثال عمل لوظيفة مستخلصات shell32 في .NET
سؤال
أحتاج إلى مثال عاملة لوظيفة المستخلصات المرتبطة في shell32.dll. لا يمكنني تشغيلها وأنا خارج الأفكار. أحتاج إلى مجموعة أخرى من العيون على الكود التالي. عند تحميل النموذج ، يجب ضبط أيقونةه على أيقونة Visual Studio ، ولكن كل ما أحصل عليه هو رمز النظام الافتراضي.
Imports System.Runtime.InteropServices
Public Class Form1
Public Function ExtractIcon(ByVal path As String, ByVal handle As IntPtr) As Icon
Dim oResult As Icon
Dim hIcon As IntPtr
Dim iIndex As Integer
Dim oPath As New System.Text.StringBuilder(260, 260)
oPath.Append(path)
hIcon = ExtractAssociatedIcon(handle, oPath, iIndex)
'hIcon = ExtractAssociatedIcon(handle, path, iIndex)
Dim oIcon As Icon = Icon.FromHandle(hIcon)
oResult = DirectCast(oIcon.Clone, Icon)
DestroyIcon(hIcon)
Return oResult
End Function
Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
ByVal hInst As IntPtr, _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As System.Text.StringBuilder, _
ByRef lpiIcon As Integer) As IntPtr
'Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
' ByVal hInst As IntPtr, _
' <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As String, _
' ByRef lpiIcon As Integer) As IntPtr
Friend Declare Auto Function DestroyIcon Lib "user32" (<[In]()> ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'ExtractAssociatedIcon uses ExtractAssociatedIcon that is in Shell32.dll.
'This works, so why doesn't mine? What am I missing?
'Me.Icon = System.Drawing.Icon.ExtractAssociatedIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
Me.Icon = ExtractIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe", Me.Handle)
End Sub
End Class
تصحيح
<MarshalAs(UnmanagedType.LPStr)>
كانت المشكلة. كان ينبغي ان يكون LPTStr
, ، ليس LPStr
.
المحلول
إن المرور في المقبض أمر خاطئ بالتأكيد ، فإن الوسيطة الأولى لـ EAI هي مقبض الوحدة النمطية ، وليس مقبض أيقونة. هذا يعمل بشكل جيد:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
...
Public Shared Function ExtractIcon(ByVal path As String, Optional ByVal index As Integer = 0) As Icon
Dim handle As IntPtr = ExtractAssociatedIcon(IntPtr.Zero, path, index)
If handle = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error())
Dim retval As Icon = Nothing
using temp As Icon = Icon.FromHandle(handle)
retval = CType(temp.Clone(), Icon)
DestroyIcon(handle)
end using
Return retval
End Function
Private Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
ByVal hInst As IntPtr, ByVal path As String, ByRef index As Integer) As IntPtr
Private Declare Auto Function DestroyIcon Lib "user32" (ByVal hIcon As IntPtr) As Boolean
لا حاجة إلى StringBuilder إذا كان مقبض الوحدة فارغًا. لا تستخدم هذا الرمز إذا لم تقم بوسيطة "الفهرس". ICON.EXTUSTASTACTICONICON ستعمل أيضًا.
نصائح أخرى
لماذا لا تستخدم ببساطة .NET الأصلي Icon.ExtractAssociatedIcon
الطريقة التي يبدو أنها تفعل الشيء نفسه؟
Me.Icon = Icon.ExtractAssociatedIcon( _
"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
ملاحظة: جربت الكود الخاص بك ، مع نفس النتيجة الخاطئة التي وصفتها. يبدو أن مقتطف الكود أعلاه يعمل.
جرب طريقة .NET Method التي تذكرها Stakx - لقد حظيت حظًا بمنحها مع حفظ ملف ICO على الرغم من ذلك (إذا قمت بحفظه كتنسيق آخر ، على سبيل المثال ، فإنه يعمل عادةً)
من أجل pinvoke somethign مثل هذا يجب أن يعمل: (التحذير ، لم يتم اختباره) المشار إليها: http://social.msdn.microsoft.com/forums/en-us/csharpgeneral/thread/ecb6137c-8bda-4468-b5e0-359caeb202b1
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo( string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags );
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
public string szTypeName;
};
private ExtractIcon()
{
}
private enum SHGFI
{
SmallIcon = 0x00000001,
LargeIcon = 0x00000000,
Icon = 0x00000100,
DisplayName = 0x00000200,
Typename = 0x00000400,
SysIconIndex = 0x00004000,
UseFileAttributes = 0x00000010
}
public static Icon GetIcon(string strPath, bool bSmall)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (bSmall)
{
flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
}
else
{
flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
}
SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}