ShellExecuteEx to open file properties on x64 not work

1.2k views Asked by At

I use the following VB.net (Framework 4) code to open file properties.
This works fine when target is set to x86.

<StructLayout(LayoutKind.Sequential)> _
Public Structure SHELLEXECUTEINFO
    Public cbSize As Integer
    Public fMask As UInteger
    Public hwnd As IntPtr
    Public lpVerb As [String]
    Public lpFile As [String]
    Public lpParameters As [String]
    Public lpDirectory As [String]
    Public nShow As Integer
    Public hInstApp As Integer
    Public lpIDList As Integer
    Public lpClass As [String]
    Public hkeyClass As Integer
    Public dwHotKey As UInteger
    Public hIcon As Integer
    Public hProcess As Integer
End Structure

Private Const SW_SHOW As Integer = 5
Private Const SEE_MASK_INVOKEIDLIST As UInteger = 12 ' 0x0000000C

<DllImport("shell32.dll")> _
Private Shared Function ShellExecuteEx(ByRef lpExecInfo As SHELLEXECUTEINFO) As Boolean
End Function

Public Shared Sub ShowProperties(ByVal path As String)
    Dim fi As New IO.FileInfo(path)
    Dim info As New SHELLEXECUTEINFO()
    info.cbSize = Marshal.SizeOf(info)
    info.lpVerb = "properties"
    info.lpFile = fi.Name
    info.lpDirectory = fi.DirectoryName
    info.nShow = SW_SHOW
    info.fMask = SEE_MASK_INVOKEIDLIST
    ShellExecuteEx(info)       
End Sub

Now I need the x64 target for my project and the code above does not work anymore. :(
GetLastError returns 0 and there is no exception or error message.
I searched two days and tried something but I found no solutiuon. Are here any ideas?

Thanks for help!

1

There are 1 answers

1
Hans Passant On BEST ANSWER
  Public hInstApp As Integer

You have several mistakes in the structure declaration, handles and pointers are IntPtr, not Integer like you declared them. Works in 32-bit code, not in 64-bit code since these fields now take 8 bytes. Use the declaration that's available on the pinvoke.net web site.

It also shows you why Marshal.GetLastError() didn't give you a proper error code, you forgot to use the SetLastError property in the [DllImport] attribute. You should also use CharSet:=CharSet.Auto in both the structure and the function declaration to benefit from Unicode.