Share this page 

Use file association to start an applicationTag(s): WinAPI/Registry


Use the external function ShellExecuteA(). The function declaration is :
FUNCTION long ShellExecuteA &
    (long hwnd, string lpOperation, &
    string lpFile, string lpParameters,  string lpDirectory, &
    integer nShowCmd ) LIBRARY "shell32"
PB10+ should use ShellExecuteW instead of ShellExecuteA

From your script, for example, to start the default browser :

string ls_Null
long   ll_rc

SetNull(ls_Null)
ll_rc = ShellExecuteA &
( handle( this ), "open", "mypahe.html", ls_Null, ls_Null, 1)
Possible return codes are:
SE_ERR_FNF              2       // file not found
SE_ERR_PNF              3       // path not found
SE_ERR_ACCESSDENIED     5       // access denied
SE_ERR_OOM              8       // out of memory
SE_ERR_DLLNOTFOUND      32
SE_ERR_SHARE            26
SE_ERR_ASSOCINCOMPLETE  27
SE_ERR_DDETIMEOUT       28
SE_ERR_DDEFAIL          29
SE_ERR_DDEBUSY          30
SE_ERR_NOASSOC          31
With the next code, it is possible to start an application associated with a specific extension to open a file (with a different extension).
[structure nvos_shellexecuteinfo]
 long      cbSize
 long      fMask
 long      hwnd
 string    lpVerb
 string    lpFile
 string    lpParameters
 string    lpDirectory
 long      nShow
 long      hInstApp
 long      lpIDList
 string    lpClass
 long      hkeyClass
 long      dwHotKey
 long      hIcon
 long      hProcess

[External Function]
FUNCTION long ShellExecuteEx(REF nvos_shellexecuteinfo lpExecInfo)
 LIBRARY "shell32.dll" ALIAS FOR ShellExecuteExA

[powerscript]
function boolean of_execute
   (readonly string as_file, readonly string as_extension)

CONSTANT long SEE_MASK_CLASSNAME = 1
CONSTANT long SW_NORMAL = 1

string ls_class
long ll_ret
nvos_shellexecuteinfo lnvos_shellexecuteinfo
Inet l_Inet

IF lower(as_extension) = "htm" OR lower(as_extension) = "html" THEN
   // Open html file with HyperlinkToURL
   // So, a new browser is launched
   // (with the code using ShellExecuteEx, it is not sure)
   GetContextService("Internet", l_Inet)
   ll_ret = l_Inet.HyperlinkToURL(as_file)
   IF ll_ret = 1 THEN
      RETURN true
   END IF
   RETURN false
END IF

// Search for the classname associated with extension
RegistryGet("HKEY_CLASSES_ROOT\." + as_extension, "", ls_class)
IF isNull(ls_class) OR trim(ls_class) = "" THEN
   // The class is not found, try with .txt (why not ?)
   RegistryGet("HKEY_CLASSES_ROOT\.txt", "", ls_class)
END IF

IF isNull(ls_class) OR Trim(ls_class) = "" THEN
   // No class : error
   RETURN false
END IF

lnvos_shellexecuteinfo.cbsize = 60
lnvos_shellexecuteinfo.fMask = SEE_MASK_CLASSNAME  // Use classname
lnvos_shellexecuteinfo.hwnd = 0
lnvos_shellexecuteinfo.lpVerb = "open"
lnvos_shellexecuteinfo.lpfile = as_file
lnvos_shellexecuteinfo.lpClass = ls_class
lnvos_shellexecuteinfo.nShow = SW_NORMAL

ll_ret = ShellExecuteEx(lnvos_shellexecuteinfo)
IF ll_ret = 0 THEN
   // Error
   RETURN false
END IF

RETURN true
For example, create the text file c:\test.txt with some lines in.
Then in Powerbuilder
// Open c:\test.txt with Word or Wordpad 
of_execute("c:\test.txt", "doc")

// Open c:\test.txt with the default browser
of_execute("c:\test.txt", "htm")
This code is useful when you want to open a file which do not have the good extension (for example, a temporary file created with the GetTempFileNameA API has a tmp extension).

Thanks to jc smondack for this tip.