我在使用以下方法启动一些快捷方式并出于某些奇怪和未知原因获取其图标时遇到问题:
Public Shared Sub Launch(itemToLaunch As String)
Process.Start(itemToLaunch)
End Sub
Public Function GetShellIcon(ByVal path As String) As Icon
Dim info As SHFILEINFO = New SHFILEINFO()
Dim retval As IntPtr = SHGetFileInfo(path, 0, info, Marshal.SizeOf(info), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_LARGEICON)
If retval = IntPtr.Zero Then
Return New Icon(GetType(Control), "Error.ico")
End If
Dim cargt() As Type = {GetType(IntPtr)}
Dim ci As ConstructorInfo = GetType(Icon).GetConstructor(BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, cargt, Nothing)
Dim cargs() As Object = {info.IconHandle}
Dim icon As Icon = CType(ci.Invoke(cargs), Icon)
Return icon
End Function
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Private Structure SHFILEINFO
Public IconHandle As IntPtr
Public IconIndex As Integer
Public Attributes As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
Public DisplayString As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
Public TypeName As String
End Structure
Private Declare Auto Function SHGetFileInfo Lib "Shell32.dll" (path As String, attributes As Integer, ByRef info As SHFILEINFO, infoSize As Integer, flags As Integer) As IntPtr
Public Const SHGFI_ICON = &H100
Public Const SHGFI_SMALLICON = &H1
Public Const SHGFI_LARGEICON = &H0 ' Large icon
这些方法几乎适用于任何项目,但有时在尝试执行快捷方式文件时会在System.dll中向我发送System.ComponentModel.Win32Exception,并在这些文件上获取其图标。
它给出了以下消息(由Process.Start给出,使用带有ErrorDialog = True的ProcessStartInfo参数调用):
如果.lnk文件的路径指向不存在的文件不正确,则此错误与引发的错误不同:
例如,您可以通过以下方式重现此问题:
在Windows 7上找到以下文件:
C:\Program Files\DVD Maker\DVDMaker.exe
(Windows 7原生)
C:\Program Files\WinRAR\WinRAR.exe
(v5.0 64位,但我猜这与另一个版本的效果相同)
C:\Program Files\Windows NT\Accessories\wordpad.exe
(Windows 7原生)
创建一个Visual Basic项目,将4个PictureBox放到Form上并命名:
还有一些帮助自己的标签。
然后将以下代码复制/粘贴到表单代码窗口中:
Imports System.Reflection
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.ExeOrigPictureBox.Tag = "C:\Program Files\WinRAR\WinRAR.exe"
Me.ExeCopyPictureBox.Tag = "C:\Users\Moi\Desktop\WinRAR.exe"
Me.LnkOrigPictureBox.Tag = "C:\Users\Moi\Desktop\WinRAR.exe linkorig.lnk"
Me.LnkCopyPictureBox.Tag = "C:\Users\Moi\Desktop\WinRAR.exe linkcopy.lnk"
Me.ExeOrigPictureBox.Image = GetShellIcon(Me.ExeOrigPictureBox.Tag).ToBitmap
Me.ExeCopyPictureBox.Image = GetShellIcon(Me.ExeCopyPictureBox.Tag).ToBitmap
Me.LnkOrigPictureBox.Image = GetShellIcon(Me.LnkOrigPictureBox.Tag).ToBitmap
Me.LnkCopyPictureBox.Image = GetShellIcon(Me.LnkCopyPictureBox.Tag).ToBitmap
End Sub
Private Sub ExeOrigPictureBox_Click(sender As Object, e As EventArgs) Handles ExeOrigPictureBox.Click, ExeCopyPictureBox.Click, LnkOrigPictureBox.Click, LnkCopyPictureBox.Click
Dim pBox As PictureBox = DirectCast(sender, PictureBox)
Dim pi As ProcessStartInfo = New ProcessStartInfo
pi.FileName = pBox.Tag
pi.ErrorDialog = True
Process.Start(pi)
End Sub
End Class
Module Shell32
Public Function GetShellIcon(ByVal path As String) As Icon
Dim info As SHFILEINFO = New SHFILEINFO()
Dim retval As IntPtr = SHGetFileInfo(path, 0, info, Marshal.SizeOf(info), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_LARGEICON)
If retval = IntPtr.Zero Then
Return New Icon(GetType(Control), "Error.ico")
End If
Dim cargt() As Type = {GetType(IntPtr)}
Dim ci As ConstructorInfo = GetType(Icon).GetConstructor(BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, cargt, Nothing)
Dim cargs() As Object = {info.IconHandle}
Dim icon As Icon = CType(ci.Invoke(cargs), Icon)
Return icon
End Function
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Private Structure SHFILEINFO
Public IconHandle As IntPtr
Public IconIndex As Integer
Public Attributes As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
Public DisplayString As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
Public TypeName As String
End Structure
Private Declare Auto Function SHGetFileInfo Lib "Shell32.dll" (path As String, attributes As Integer, ByRef info As SHFILEINFO, infoSize As Integer, flags As Integer) As IntPtr
Public Const SHGFI_ICON = &H100
Public Const SHGFI_SMALLICON = &H1
Public Const SHGFI_LARGEICON = &H0 ' Large icon
End Module
然后执行。
您将获得以下内容:
点击任何一个显示良好的图标即可启动WinRar应用程序 单击显示错误的图标会显示以下错误:
使用Me.LnkOrigPictureBox.Tag
这样的错误路径更改"C:\Users\Moi\Desktop\WinRARdontexistshere.exe linkorig.lnk"
的值并执行相同的操作会显示另一个视觉和错误(如预期的那样):
这不适用于DVDMaker.exe
但wordpad.exe
,图标和应用程序启动一切正常。
(我已经测试了大写/小写的情况,看它是否干扰,但这不是问题)
我已经注意到其他一些应用程序的问题,但没有理解其中的原因,例如:
和其他标准Windows应用。
将有问题的文件路径C:\Users\Moi\Desktop\WinRAR.exe linkorig.lnk
复制/粘贴到Windows资源管理器标题栏上时,会启动WinRAR.exe应用程序。
当然,同样重要的是我双击.lnk文件。
复制/粘贴到Windows-R命令窗口时,它也可以很好地启动。
如果通过从放置在WinRAR.lnk
文件夹中的命令行窗口输入C:\Users\Moi\Desktop\
来调用,也会启动。
我正在运行Windows 7 64位。该应用程序使用Visual Studio Express 2015进行编译。我以管理员身份登录(在Windows安装中创建的唯一默认帐户)。运行已编译的应用程序&#34;作为管理员&#34;不改变任何东西。
我尝试使用以下某些配置但未成功:
Dim info As ProcessStartInfo = New ProcessStartInfo(--- here the path ---)
info.CreateNoWindow = False
info.UseShellExecute = False
info.RedirectStandardError = True
info.RedirectStandardOutput = True
info.RedirectStandardInput = True
Dim whatever As Process = Process.Start(info)
我怎样才能解决这个启动问题,以及这些文件的图标检索问题?
答案 0 :(得分:0)
Woow ...当我看到,通过网络上发现的一些示例进行一些测试时,我找到了运气的答案,当使用标准时,图标问题和尝试使用相应文件时的错误消息也存在OpenFileDialog
。我怀疑.Net框架中有一个错误。解决方案就在这附近,我仍然不太了解它的深层原因。
问题如下:
默认情况下,项目已定义为与.Net Framework 4.5一起运行的项目设置
我将其切换为使用Framework 4运行 运行应用程序:没有问题
我将其切换回与Framework 4.5一起运行 没有更多问题。