PInvoke und Interop-Code am Beispiel ShGetFileInfo
Frank Dzaebel, erstellt am: 24.05.2005, zuletzt geändert: 24.05.2005
Kategorie: Interop, .NET-Version: 1.1
Der folgende Code stellt Kommunikations-Möglichkeiten zwischen .NET-C# und der Windows API beispielhaft anhand der SHGetFileInfo-Funktion, SHFILEINFO-struct und dem Enum SHGFI dar. Die Funktion wurde auf XP/Prof und Windows98 getestet. Relevante Interop-Links werden aufgeführt.
Weiterführende Artikel über C# und Interop-Techniken:
Lernprogramm für die Plattformaktivierung
COM-Interop Teil 1: C#-Clientlernprogramm
C# Tipps - Interoperabilität mit nicht verwaltetem Code
Mit C# arbeiten - Verwenden von Win32 und anderen Bibliotheken
So arbeitet .NET mit Win32 und COM zusammen
Marshal-Klasse, PInvoke.NET
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Reflection;
namespace MarshalSizeof
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnByVal;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{ if(disposing) if (components != null) components.Dispose();
base.Dispose(disposing);
}
#region Vom Windows Form-Designer generierter Code
private void InitializeComponent()
{
this.btnByVal = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnByVal
//
this.btnByVal.Location = new System.Drawing.Point(26, 31);
this.btnByVal.Name = "btnByVal";
this.btnByVal.Size = new System.Drawing.Size(53, 24);
this.btnByVal.TabIndex = 0;
this.btnByVal.Text = "ByVal";
this.btnByVal.Click += new System.EventHandler(this.btnByVal_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnByVal);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnByVal_Click(object sender, System.EventArgs e)
{
string path = Application.ExecutablePath;
SHFILEINFO fi;
SHGetFileInfo(path, 0, out fi,
(uint)Marshal.SizeOf(typeof(SHFILEINFO)),
SHGFI.DisplayName);
MessageBox.Show("Displayname = " + fi.szDisplayName);
}
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
private static extern int SHGetFileInfo(
string pszPath ,
int dwFileAttributes,
out SHFILEINFO psfi ,
uint cbfileInfo ,
SHGFI uFlags );
[Flags]
enum SHGFI : int
{
/// <summary>get icon</summary>
Icon = 0x000000100,
/// <summary>get display name</summary>
DisplayName = 0x000000200,
/// <summary>get type name</summary>
TypeName = 0x000000400,
/// <summary>get attributes</summary>
Attributes = 0x000000800,
/// <summary>get icon location</summary>
IconLocatin = 0x000001000,
/// <summary>return exe type</summary>
ExeType = 0x000002000,
/// <summary>get system icon index</summary>
SysIconIndex = 0x000004000,
/// <summary>put a link overlay on icon</summary>
LinkOverlay = 0x000008000,
/// <summary>show icon in selected state</summary>
Selected = 0x000010000,
/// <summary>get only specified attributes</summary>
Attr_Specified = 0x000020000,
/// <summary>get large icon</summary>
LargeIcon = 0x000000000,
/// <summary>get small icon</summary>
SmallIcon = 0x000000001,
/// <summary>get open icon</summary>
OpenIcon = 0x000000002,
/// <summary>get shell size icon</summary>
ShellIconize = 0x000000004,
/// <summary>pszPath is a pidl</summary>
PIDL = 0x000000008,
/// <summary>use passed dwFileAttribute</summary>
UseFileAttributes= 0x000000010,
/// <summary>apply the appropriate overlays</summary>
AddOverlays = 0x000000020,
/// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
OverlayIndex = 0x000000040,
}
/// <summary>Maximal Length of unmanaged Windows-Path-strings</summary>
private const int MAX_PATH = 260;
/// <summary>Maximal Length of unmanaged Typename</summary>
private const int MAX_TYPE = 80 ;
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
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.ByValTStr, SizeConst=MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_TYPE)]
public string szTypeName;
};
}
}