cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Snoopstah
Level 7

InstallScript custom DLL call

In my previous Basic MSI project, I launched a window from which users could select a folder. This was done via custom action DLL call. The CA function looked like the attached image dllcall.jpg.

This CA was called from a "Browse" button on a dialog and returned a property [SERVER_DATA_PATH], as can be seen in SetProperty.jpg.

I am rewriting this installer as an InstallScript project and am having a great deal of difficulty getting the return value from this DLL. My code looks like:

prototype LONG HCNBrowseNetwork.BrowseForBlueChipDataPath(HWND, HWND);
.
.
.
case BlueData_Browse:
// Launch windows explorer browse window
UseDLL (szDll);
BrowseForBlueChipDataPath(0,0);
nBuffer = 128;
if (MsiGetProperty(ISMSI_HANDLE, "SERVER_DATA_PATH", svBlueDataPath, nBuffer)) = ERROR_SUCCESS then
MessageBox ("SERVER_DATA_PATH = " + svBlueDataPath, INFORMATION);
else
MessageBox ("MsiGetProperty fails", SEVERE);
endif;
CtrlSetText (szDialogName, BlueData_Edit, svBlueDataPath);
UnUseDLL(szDll);


The browse dialog is showing and allows me to select a valid folder, however that folder seems to never be returned into anything.
What have I done wrong in my scripting?
Labels (1)
0 Kudos
(8) Replies
RobertDickau
Flexera Alumni

Since InstallScript doesn't use MSI properties, the DLL would presumably need to be changed not to use properties to convey information back to the installer (that is, any MsiSetProperty calls in the DLL will need to be changed to BYREF variables, or some such thing).

If the point of the DLL function is just to browse for a folder, perhaps see if SelectDirEx or the like will work instead?
0 Kudos
Snoopstah
Level 7

SelectDirEx is a MUCH easier way to do this. Thankyou !!!
0 Kudos
Snoopstah
Level 7

I noticed if a user puts an invalid path in, the function automatically lets them know and reverts back to the browse dialog. This is great.

BUT (there's always a but...)

Each time I type a single character back into the edit field of the browse dialog, the dialog loses focus and I need to click in the edit field and type a character VERY quickly before it loses focus again.

Why is it doing this and is there a workaroun ?
0 Kudos
William-Webb
Level 4

I know it's a bit late but if you put this code around the call to SelectDirEx...

Before:

hMsiWindow = GetWindowHandle( HWND_INSTALL );
if ( hMsiWindow ) then
ShowWindow( hMsiWindow, SW_HIDE );
endif;


After:

if ( hMsiWindow ) then
ShowWindow( hMsiWindow, SW_SHOW );
endif;


This should fix your focusing issue, I know it did for ours! 🙂
0 Kudos
Snoopstah
Level 7

Never too late. The code does indeed stop the loss of focus, however I now seem to be in a never ending loop.

When the user types in a VALID path, the box is refreshed with my "default" value and I can never exit the dialog...

Here is my code:

repeat
// Set a default folder for the SelectDirEx dialog.
svDir = WSBLUEDATAPATH;
szTitle = "Select path to the Server BlueData folder";
szMsg = "Please choose an existing folder.";
// Make sure the window does not lose focus
hMsiWindow = GetWindowHandle( HWND_INSTALL );
if ( hMsiWindow ) then
ShowWindow( hMsiWindow, SW_HIDE );
endif;
// Get an existing folder name from the user.
nResult = SelectDirEx (szTitle, szMsg, "", "", BIF_RETURNONLYFSDIRS | BIF_EDITBOX, svDir );
// Make sure the window does not lose focus
if ( hMsiWindow ) then
ShowWindow( hMsiWindow, SW_SHOW );
endif;
if nResult = 0 then
// Determine whether the folder exists.
bFolderExists = ExistsDir (svDir);
if bFolderExists = NOTEXISTS then
// The folder does not exist. Ask user to select again.
szMsg = "%s does not exist.\nPlease choose an existing folder.";
SprintfBox (WARNING, szTitle, szMsg, svDir);
else
// Folder exists but it cannot be a local folder.
ParsePath ( svReturnPath, svDir, DISK );
StrSub ( svSubStr, svReturnPath, 0, 2);
if svSubStr = "\\\\" then
// All ok - this is a server path
else
// The folder is a local folder, which is not allowed.
szMsg = "%s is a local folder.\nPlease choose a folder on the server.";
SprintfBox (WARNING, szTitle, szMsg, svDir);
endif;
endif;
endif;
until (nResult = CANCEL) || ((bFolderExists = EXISTS) && (svSubStr = "\\\\"));
0 Kudos
Snoopstah
Level 7

My bad!

somewhere along the way I changed my code and needed to implement the bold bits.

nResult = (SelectDirEx (szTitle, szMsg, "", "", BIF_RETURNONLYFSDIRS | BIF_EDITBOX, svDir ) < 0);
0 Kudos
William-Webb
Level 4

Snoopstah wrote:
My bad!

somewhere along the way I changed my code and needed to implement the bold bits.

nResult = (SelectDirEx (szTitle, szMsg, "", "", BIF_RETURNONLYFSDIRS | BIF_EDITBOX, svDir ) < 0);


I was going to say, if you remove those brackets it should work fine 🙂
0 Kudos
Snoopstah
Level 7

Another more stable solution was to add the following on my OnBegin() function so it propogates through all dialogs

hMain = GetWindowHandle( HWND_INSTALL );
SetWindowLong( hMain, GWL_STYLE, GetWindowLong( hMain,GWL_STYLE ) | WS_OVERLAPPEDWINDOW );
SetWindowPos( hMain, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_HIDEWINDOW );
0 Kudos