Reputation: 2528
I have a windows .net program that (among other things) will display image files. These can be in either TIFF or PDF format, and at the moment the way they are displayed is to see what the file extension is, then to call the appropriate program to display that file.
Here's the code fragment:
imagepath = imagedataset.Tables("Table").Rows(imagecal).Item(2)
imagepath = "\\tylerimaging\DocumentUpload\" & imagedataset.Tables("Table").Rows(imagecal).Item(3) & "\" & imagedataset.Tables("table").Rows(imagecal).Item(4)
Dim PDFImage As String = imagepath.Substring(imagepath.Length - 3)
If UCase(PDFImage) = "PDF" Then
System.Diagnostics.Process.Start("AcroRd32.exe", imagepath)
Else
Try
System.Diagnostics.Process.Start("MSPVIEW.EXE", imagepath)
Catch ex As Exception
If ex.Message = "The system cannot find the file specified" Then
System.Diagnostics.Process.Start("ois.exe", imagepath)
End If
End Try
End If
End If
Now, the problem is that if someone doesn't have the acrobat reader installed, for example, but the full version of adobe acrobat, the process.start for AcroRd32.exe will fail. But, Windows clearly has the association between the file type of PDF and Acrobat - so, here's my question - how can I get the file displayed by whatever program is associated with that file type in Windows?
Thanks in Advance....
Upvotes: 2
Views: 595
Reputation: 44971
We have implemented a common library set of methods that will first attempt to open the file using Process.Start and, if that fails, prompt the user to select the application to open the file with (open as).
This implementation also addresses a legacy issue where opening RTF files would throw an InvalidOperationException. The usual entry point is to call OpenFileForUser with the full path to the file.
Public Structure SHELLEXECUTEINFO
Public Size As Integer
Public Mask As Integer
Public hwnd As IntPtr
<MarshalAs(UnmanagedType.LPStr)> Public Verb As String
<MarshalAs(UnmanagedType.LPStr)> Public File As String
<MarshalAs(UnmanagedType.LPStr)> Public Parameters As String
<MarshalAs(UnmanagedType.LPStr)> Public Directory As String
Dim Show As Integer
Dim InstApp As IntPtr
Dim IDList As IntPtr
<MarshalAs(UnmanagedType.LPTStr)> Public [Class] As String
Public hkeyClass As IntPtr
Public HotKey As Integer
Public Icon As IntPtr
Public Process As IntPtr
End Structure
Public Const SW_NORMAL As Integer = 1
' Code For OpenWithDialog Box
<DllImport("Shell32", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Function ShellExecuteEx(ByRef lpExecInfo As SHELLEXECUTEINFO) As Boolean
End Function
''' <summary>
''' This method executes the shell method for opening the specified file, allowing the user to choose
''' which program they would like to use to open the file.
''' </summary>
''' <param name="sFileName"></param>
''' <remarks></remarks>
Public Sub OpenFileForUserAs(ByVal sFileName As String)
' Exceptions are handled by the caller
Dim oShellExecuteInfo As New SHELLEXECUTEINFO
With oShellExecuteInfo
.Size = System.Runtime.InteropServices.Marshal.SizeOf(oShellExecuteInfo)
.Verb = "openas"
.File = sFileName
.Show = SW_NORMAL
End With
If Not ShellExecuteEx(oShellExecuteInfo) Then
Throw New System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error())
End If
End Sub
''' <summary>
''' This method opens the file for the user
''' </summary>
''' <param name="sFileName"></param>
''' <remarks></remarks>
Public Function OpenFileForUser(ByVal sFileName As String) As System.Diagnostics.Process
' Exceptions are handled by the caller
Try
Return System.Diagnostics.Process.Start(sFileName, "")
Catch theInvalidOperation As InvalidOperationException
' happens with rtf; just sink the exception
Catch ex As System.ComponentModel.Win32Exception
Select Case ex.NativeErrorCode
Case 1155
Call OpenFileForUserAs(sFileName)
Case 1223
' Operation Cancelled By User
Case Else
Throw ex
End Select
End Try
Return Nothing
End Function
Upvotes: 0
Reputation: 613461
Call Process.Start() passing just the document file name. By default this uses the UseShellExecute option which means that the shell is asked to perform the open verb on the document. That's the same as double clicking the document from the shell UI.
Upvotes: 2
Reputation: 81675
Try calling Process.Start on the PDF or TIFF file itself. Windows will take care of it or raise an exception if nothing is associated with the file type.
Upvotes: 4