Click to See Complete Forum and Search --> : Opening Files with associated programs?


brian stjacques
March 20th, 2001, 12:17 PM
I would like to know how to send files to the operating system from VB to be opened by the program that the file is associated with (basically the equivalent of double clicking a file in Explorer). The closest I can find is the shell command which requires a specific target program to open the file with. TIA.

B.S.

Clearcode
March 20th, 2001, 12:42 PM
You can use the ShellExecute API thus:
Declaration:


private Declare Function ShellExecute _
Lib "shell32.dll" Alias "ShellExecuteA" (byval _
hwnd as Long, byval lpOperation as string, byval lpFile as string, byval lpParameters as string, byval lpDirectory as string, byval nShowCmd as Long) as Long





Use:


'\\-[OpenDocument]-----------------------------------------------------
'\\ Opens the document using the app. which created it.
'\\ (Similar to selecting "open" from explorer context menu)
'\\ --------------------------------------------------------------------
'\\ You have a royalty free right to use, reproduce, modify, publish and mess with this code
'\\ I'd like you to visit http://www.merrioncomputing.com for updates, but won't force you
'\\ ----------------------------------------------------------------------------------------

public Sub OpenDocument(byval sDocumentName as string)
Const SW_HIDE = 0
Dim lRet as Long

lRet = ShellExecute(0, "open", sDocumentName, "", "", SW_HIDE)

End Sub





-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com

John G Duffy
March 20th, 2001, 12:47 PM
Thee is a Windows API which does this, called SHellExecute. Below is an example:
Start a new project, Add a Command button and A CommonDialog control to the form. Ad a Module to the project.

' Paste this code into the Form
private Sub Command1_Click()
CommonDialog1.InitDir = "C:\My Documents"

CommonDialog1.ShowOpen
ShellExecAndWait CommonDialog1.FileName, true
End Sub
'
'
' Paste this code into the Module.
NOTE. I did not write this code. The authors name is in the Module comments
'
'**************************************************************
' Windows API Declarations for ShellExecAndWait
' COPY THESE DECLARATIONS to THE GENERAL DECLARATIONS SECTION
'**************************************************************
' Name: ShellExecute to a Document, and Wait for it to End
' Description:This procedure performs a ShellExecute API Call (Wi
' n95/98 and now NT) to open a file with it's associated program, a
' nd then Waits for that program to end. Download a sample .zip of
' this program from: http://www.StotzerSoftware.com. Most Shell fun
' ctions that wait for the program to terminate, must shell to the
' .exe. This will Shell to a 'file' using the ShellExecute API to l
' oad the file into it's associated program, then it will wait for
' that program to end.
' By: Andy Stotzer
'
'
' Inputs:The PathFilename of the file to open.
'A Wait Flag.
'optional: Form object.
'
' Returns:nothing
'
'Assumes:None
'
'Side Effects:None
'
'Code provided by Planet Source Code(tm) (http://www.Planet-Sourc
' e-Code.com) 'as is', without warranties as to performance, fitnes
' s, merchantability,and any other warranty (whether expressed or i
' mplied).
'Distribution of this source code is copyrighted by Planet Source
' Code who has exclusive rights to distribute it.
'It is freely redistributable for personal use in source code for
' m, or for personal or business use in a non-source code binary ex
' ecutable.
'All other redistributions are prohibited without express written
' consent from Exhedra Solutions, Inc.
'***************************************************************

'***************************************************************
'Windows API/Global Declarations for :ShellExecute to a Document,
' and Wait for it to End

private Const PROCESS_QUERY_INFORMATION = &H400
private Const TH32CS_SNAPPROCESS as Long = 2&
private Const MAX_PATH as Integer = 260
private Const SW_SHOW as Integer = 5

private Type PROCESSENTRY32
dwSize as Long
cntUsage as Long
th32ProcessID as Long
th32DefaultHeapID as Long
th32ModuleID as Long
cntThreads as Long
th32ParentProcessID as Long
pcPriClassBase as Long
dwFlags as Long
szExeFile as string * MAX_PATH
End Type

private Declare Function GetCurrentProcessId Lib "kernel32" () as Long
private Declare Function GetExitCodeProcess Lib "kernel32" (byval hProcess as Long, lpExitCode as Long) as Long
private Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (byval lFlags as Long, byval lProcessID as Long) as Long
private Declare Function OpenProcess Lib "kernel32" (byval dwDesiredAccess as Long, byval bInheritHandle as Long, byval dwProcessId as Long) as Long
private Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (byval hSnapShot as Long, uProcess as PROCESSENTRY32) as Long
private Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (byval hSnapShot as Long, uProcess as PROCESSENTRY32) as Long
private Declare Function CloseHandle Lib "kernel32" (byval hObject as Long) as Long
private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (byval hwnd as Long, byval lpOperation as string, byval lpFile as string, byval lpParameters as string, byval lpDirectory as string, byval nShowCmd as Long) as Long
' Windows Version API Calls '

Type OSVERSIONINFO
dwOSVersionInfoSize as Long
dwMajorVersion as Long
dwMinorVersion as Long
dwBuildNumber as Long
dwPlatformId as Long
szCSDVersion as string * 128
End Type
public Const VER_PLATFORM_WIN32s = 0
public Const VER_PLATFORM_WIN32_WINDOWS = 1
public Const VER_PLATFORM_WIN32_NT = 2

private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (byref lpVersionInformation as OSVERSIONINFO) as Long

public Type PROCESS_BASIC_INFORMATION
ExitStatus as Long
PebBaseAddress as Long
AffinityMask as Long
BasePriority as Long
UniqueProcessId as Long
InheritedFromUniqueProcessId as Long 'ParentProcessID'
End Type


public Declare Function NtQueryInformationProcess _
Lib "ntdll" (byval ProcessHandle as Long, _
byval ProcessInformationClass as Long, _
byref ProcessInformation as PROCESS_BASIC_INFORMATION, _
byval lProcessInformationLength as Long, _
byref lReturnLength as Long) as Long


public Declare Function EnumProcesses Lib "psapi.dll" (byref lpidProcess as Long, byval cb as Long, byref cbNeeded as Long) as Long
public Const PROCESS_VM_READ = 16

'***************************************************************

public Sub ShellExecAndWait(sFilename as string, _
bWaitToEnd as Boolean, optional oForm as Variant)

Dim hSnapShot as Long
Dim hProcess as Long
Dim uProcess as PROCESSENTRY32
Dim lRC as Long
Dim lShelledProcessID as Long
Dim lMyProcessID as Long
Dim myOS as OSVERSIONINFO
Dim iWinVersion as Integer
'--WARNING:-------------------------------------------
' This procedure may/will NOT WORK correctly if you
' Shell to more than one application at a time. It
' only looks for the first Process that has your
' program as the Parent.
'-----------------------------------------------------

'--- get THIS APPS PROCESS ID ---'
lMyProcessID = GetCurrentProcessId
'--- SHELLEXECUTE THE DOCUMENT to THE ASSOCIATED APP ---'
If IsMissing(oForm) then
lRC = ShellExecute(0&, "open", sFilename, vbNullString, CurDir$, SW_SHOW)
else
lRC = ShellExecute(oForm.hwnd, "open", sFilename, vbNullString, CurDir$, SW_SHOW)
End If
If lRC < 32 then
MsgBox "Unable to open this file: " & vbLf & " " & sFilename, vbExclamation, "error Opening File"
Exit Sub
End If
'-----------------------'
'Wait for Process to End'
'-----------------------'
If Not bWaitToEnd then
Exit Sub
End If
'FIND OUT WHAT VERSION OF WINDOWS is RUNNING'
myOS.dwOSVersionInfoSize = len(myOS)
GetVersionEx myOS
If myOS.dwMajorVersion = 4 then
iWinVersion = myOS.dwPlatformId
else
MsgBox "You need to upgrade your version of windows to use the 'Wait for Process to End' feature of this function: 'ShellExecAndWait'.", vbExclamation, "Sorry!"
Exit Sub
End If
'WHAT VERSION OF WINDOWS ARE THEY RUNNING?'
Select Case iWinVersion
Case VER_PLATFORM_WIN32_NT
Dim cb as Long
Dim cbNeeded as Long
Dim NumElements as Long
Dim ProcessIDs() as Long
Dim lRet as Long
Dim i as Long
'get AN ARRAY OF PROCESS IDS'
cb = 8
cbNeeded = 96
Do While cb <= cbNeeded
cb = cb * 2
ReDim ProcessIDs(cb / 4) as Long
lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
Loop
NumElements = cbNeeded / 4
for i = 1 to NumElements
'get a handle to the Process
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, ProcessIDs(i))
'--------------------------------'
' FIND THE NT PARENT PROCESS ID '
'--------------------------------'
Dim lntStatus as Long
Dim lProcessHandle as Long
Dim lProcessBasicInfo as Long
Dim tProcessInformation as PROCESS_BASIC_INFORMATION
Dim lProcessInformationLength as Long
Dim lReturnLength as Long
'INITIALIZE EVERYTHING'
lProcessHandle = hProcess
lProcessBasicInfo = 0 '0 = REQUEST PROCESS INFORMATION'
lProcessInformationLength = len(tProcessInformation)
'CALL NT FUNCTION to FIND PROCESS INFORMATION'
lntStatus = NtQueryInformationProcess(lProcessHandle, lProcessBasicInfo, tProcessInformation, lProcessInformationLength, lReturnLength)
'AM I THE PARENT OF THIS PROCESS?'
If lMyProcessID = tProcessInformation.InheritedFromUniqueProcessId then
lShelledProcessID = tProcessInformation.UniqueProcessId
'CLOSE THE HANDLE to THE PROCESS'
lRet = CloseHandle(hProcess)
Exit for
End If
'CLOSE THE HANDLE to THE PROCESS'
lRet = CloseHandle(hProcess)
next
Case VER_PLATFORM_WIN32_WINDOWS
' WINDOWS 95/98 '
'--------------------------------'
' FIND THE 95 PARENT PROCESS ID '
'--------------------------------'
hSnapShot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
If hSnapShot = 0 then Exit Sub
uProcess.dwSize = len(uProcess)
lRC = ProcessFirst(hSnapShot, uProcess)
Do While lRC
'AM I THE PARENT OF THIS PROCESS?'
If lMyProcessID = uProcess.th32ParentProcessID then
'FOUND IT'
lShelledProcessID = uProcess.th32ProcessID
Exit Do
End If
lRC = ProcessNext(hSnapShot, uProcess)
Loop
'CLOSE THE HANDLE to THE PROCESS'
Call CloseHandle(hSnapShot)
Case else
End Select
'--- WAIT for PROCESS to END ---'
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, lShelledProcessID)
Do
Call GetExitCodeProcess(hProcess, lRC)
DoEvents
Loop While lRC > 0
Call CloseHandle(hProcess)
End Sub



'
'
Run the program

John G