Comment obtenir l'icône associée à partir d'un fichier de partage réseau
J'utilise L'icône.ExtractAssociatedIcon pour obtenir l'icône d'un fichier , que l'utilisateur sélectionne, dans un openfiledialog.
le problème est que si l'utilisateur sélectionne une icône à partir d'un partage de réseau, alors la propriété filename du openfiledialog est au format UNC et cela provoque un ArgumentException
ExtractAssocaitedIcon
:
Value of 'serversharefilename' is not valid for 'filePath'.
Stack Trace:
at System.Drawing.Icon.ExtractAssociatedIcon(String filePath, Int32 index)
ainsi, ma question reçoit un fichierserversharefilename
, comment obtenir l'icône?
Remarque: .NET 2.0
4 réponses
regarde ce Réflecteur, c'est finalement l'appel de ExtractAssociatedIcon
shell32.dll
.
avez-vous essayé de contourner la BCL en y accédant via PInvoke?
un Exemple de code (à l'aide de PInvoke.Net):
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
static extern IntPtr ExtractAssociatedIcon(IntPtr hInst, StringBuilder lpIconPath,
out ushort lpiIcon);
// ... snip
ushort uicon;
StringBuilder strB = new StringBuilder(260); // Allocate MAX_PATH chars
strB.Append(openFileDialog1.FileName);
IntPtr handle = ExtractAssociatedIcon(IntPtr.Zero, strB, out uicon);
Icon ico = Icon.FromHandle(handle);
pictureBox1.Image = ico.ToBitmap();
// ... snip
à des fins d'exhaustivité, voici un ExtractAssociatedIcon
une routine qui fonctionne:
/// <summary>
/// Returns an icon representation of an image contained in the specified file.
/// This function is identical to System.Drawing.Icon.ExtractAssociatedIcon, xcept this version works.
/// </summary>
/// <param name="filePath">The path to the file that contains an image.</param>
/// <returns>The System.Drawing.Icon representation of the image contained in the specified file.</returns>
/// <exception cref="System.ArgumentException">filePath does not indicate a valid file.</exception>
public static Icon ExtractAssociatedIcon(String filePath)
{
int index = 0;
Uri uri;
if (filePath == null)
{
throw new ArgumentException(String.Format("'{0}' is not valid for '{1}'", "null", "filePath"), "filePath");
}
try
{
uri = new Uri(filePath);
}
catch (UriFormatException)
{
filePath = Path.GetFullPath(filePath);
uri = new Uri(filePath);
}
//if (uri.IsUnc)
//{
// throw new ArgumentException(String.Format("'{0}' is not valid for '{1}'", filePath, "filePath"), "filePath");
//}
if (uri.IsFile)
{
if (!File.Exists(filePath))
{
//IntSecurity.DemandReadFileIO(filePath);
throw new FileNotFoundException(filePath);
}
StringBuilder iconPath = new StringBuilder(260);
iconPath.Append(filePath);
IntPtr handle = SafeNativeMethods.ExtractAssociatedIcon(new HandleRef(null, IntPtr.Zero), iconPath, ref index);
if (handle != IntPtr.Zero)
{
//IntSecurity.ObjectFromWin32Handle.Demand();
return Icon.FromHandle(handle);
}
}
return null;
}
/// <summary>
/// This class suppresses stack walks for unmanaged code permission.
/// (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.)
/// This class is for methods that are safe for anyone to call.
/// Callers of these methods are not required to perform a full security review to make sure that the
/// usage is secure because the methods are harmless for any caller.
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shell32.dll", EntryPoint = "ExtractAssociatedIcon", CharSet = CharSet.Auto)]
internal static extern IntPtr ExtractAssociatedIcon(HandleRef hInst, StringBuilder iconPath, ref int index);
}
Remarque:: tout code est publié dans le domaine public. Aucune attribution n'est requise.
une méthode pour accomplir ceci est de récupérer votre chemin UNC et de le mapper temporairement à une lettre de lecteur, puis d'utiliser ce lecteur dans votre .Méthode ExtractAssociatedIcon. Lorsque vous avez récupéré l'icône, vous pouvez démonter le lecteur. Ce n'est pas Élégant, mais ça devrait marcher.
une autre option serait de copier le fichier que l'utilisateur sélectionne à leur % TEMP % et d'utiliser Icon.ExtractAssociatedIcon
il n'. N'oubliez pas de nettoyage après vous-même.
évidemment pas une bonne solution si vous supportez de gros fichiers!