Thursday, May 25, 2006

RUN and GetShortPathName

Stonefield Query has a function in its developer interface (the Configuration Utility) to generate an InnoSetup script and compile it into a setup executable. The idea is to make it as easy as possible for someone to deploy a custom Stonefield Query application without having to be an installer expert. Generating the script is easy because InnoSetup scripts are just text files. Compiling the script is also easy: use the RUN command to call the InnoSetup compiler, passing it the name of the script file to compile.

I get the location of the compiler from the Windows Registry, at HKEY_CLASSES_ROOT\'InnoSetupScriptFile\Shell\Compile\Command, which on my system gives "D:\Program Files\Inno Setup 5\Compil32.exe" /cc "%1". So, it's a simple matter to read this value into a variable (for example, lcInnoCompiler) and then:

lcInnoCompiler = strtran(lcInnoCompiler, '%1', lcScriptFile)
run /n1 &lcInnoCompiler

This works great on my system and lots of customers' systems. However, one of our sales guys (Jeff Zinnert) reported that he got a "RUN command failed; file does not exist" error when he tried it and so did a customer. We checked that the InnoCompiler was installed correctly, in the place the Registry said it was, and that the script file existed, but to no avail.

While pondering this, I came across a message on the Universal Thread that was completely unrelated but mentioned an issue with "short" (ie. the old DOS 8.3) paths. That reminded me of a similar issue I'd run into several years ago but had forgotten about. A function I'd written years ago calls the Windows API GetShortPathName function to convert a "long" path into a short one:

lparameters tcPath
local lcPath, ;
lnLength, ;
lcBuffer, ;
lnResult
declare integer GetShortPathName in Win32API ;
string @lpszLongPath, string @lpszShortPath, integer cchBuffer
lcPath = tcPath
lnLength = 260
lcBuffer = space(lnLength)
lnResult = GetShortPathName(@lcPath, @lcBuffer, lnLength)
return iif(lnResult = 0, '', left(lcBuffer, lnResult))

I used this function to convert the paths in the lcInnoCompiler variable to short paths and Jeff and the customer no longer get this error.

Once again, the UT saves my butt even though the answer wasn't directly there.

1 comment:

Anonymous said...

Just when you think you have Doug stumped, he figures out a solution!

One of these days i'll stump him!