lcSystem = Thisform.oUtility.GetSystemDirectory()(GetSystemDirectory is a utility method that returns the location of the Windows System folder; I'll show the code for that later.)
try
run /n1 &lcSystem..odbcad32.exe
catch
endtry
This worked great until I tried it on Vista; it fails there because the ODBC Administrator requires admin privileges and the RUN command doesn't support requesting elevation. Fortunately, there's an easy solution to that: use ShellExecute instead. I changed the code to:
lcSystem = oUtility.GetSystemDirectory()(Like GetSystemDirectory, ShellExecute is another utility function. It runs the specified command. The cool thing about ShellExecute is that it'll launch the appropriate program. In the case of an EXE, it runs it. In the case of an HTML file, it launches the default browser. In the case of a DOC file, it launches Word.)
try
oUtility.ShellExecute(lcSystem + 'odbcad32.exe', 'RunAs')
catch
endtry
Now when the user clicks the button, they're requested to elevate to administrator before the ODBC Administrator appears. To make it obvious that this will happen, I've followed the Vista convention of adding a shield image to the button to alert the user that elevation will be requested. To do that, I set PicturePosition to 1-Left of Caption, Picture to VistaShield.BMP (an image I created using SnagIt to grab the shield icon displayed in the User Accounts control panel applet), and shortened Caption to just "ODBC" so it all fits. Here's what the button looks like:
Here's the code for GetSystemDirectory:
#define cnMAX_PATH 260Here's the code for ShellExecute:
#define ccNULL chr(0)
local lcBuffer
lcBuffer = space(cnMAX_PATH)
declare integer GetSystemDirectory in Win32API ;
string @szBuffer, integer nLength
GetSystemDirectory(@lcBuffer, cnMAX_PATH)
return addbs(alltrim(left(lcBuffer, at(ccNULL, lcBuffer) - 1)))
lparameters tcFileName, ;
tcOperation, ;
tcWorkDir, ;
tcParameters
local lcFileName, ;
lcWorkDir, ;
lcOperation, ;
lcParameters, ;
lnShow
if empty(tcFileName)
return -1
endif empty(tcFileName)
lcFileName = alltrim(tcFileName)
lcWorkDir = iif(vartype(tcWorkDir) = 'C', alltrim(tcWorkDir), '')
lcOperation = iif(vartype(tcOperation) = 'C' and not empty(tcOperation), ;
alltrim(tcOperation), 'Open')
lcParameters = iif(vartype(tcParameters) = 'C', alltrim(tcParameters), '')
lnShow = iif(upper(lcOperation) = 'Print', 0, 1)
declare integer ShellExecute in SHELL32.DLL ;
integer nWinHandle, ; && handle of parent window
string cOperation, ; && operation to perform
string cFileName, ; && filename
string cParameters, ; && parameters for the executable
string cDirectory, ; && default directory
integer nShowWindow && window state
return ShellExecute(0, lcOperation, lcFilename, lcParameters, lcWorkDir, ;
lnShow)