cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
blood_on_ice
Level 4

Calling BrowseForFile DLL

Hello!

I try to use the BrowseForFile DLL from http://www.installsite.org/files/iswi/BrowseForFile.zip I inserted the BrowseForFile.dll in the support files section.

Then I do the following in the install-script:
prototype BYREF STRING BrowseForFile.BrowseForFile(BYREF STRING, BYREF STRING);

szFilter = "Certificate File (*.cer)\0*.cer\0";
UseDLL(SUPPORTDIR ^ "BrowseForFile.DLL");
BrowseForFile.BrowseForFile(szCertificatePath, szFilter);
MessageBox( "Selected Path: " + szCertificatePath, INFORMATION );
UnUseDLL(SUPPORTDIR ^ "BrowseForFile.DLL");

I get the error 0x80040704

What's the problem, how can i prototype this function and call it after that?

Here's the code of the dll:
[CODE]
//***********************************************************
//** This source code is provided "AS IS" with no warranties,
//** and confers no rights.
//***********************************************************

#include
#include
#include
#include
#include "msiquery.h"
#include "strsafe.h"

//***********************************************************
//** Call back function for EnumChildWindows()
//**---------------------------------------------------------
//** Author: Kallely L Sajan
//***********************************************************
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
TCHAR buf[100];
GetClassName( hwnd, (LPTSTR)&buf, 100 );

if ( _tcscmp ( buf, (_T("RichEdit20W")) ) == 0 )
{
*(HWND*)lParam = hwnd;
return FALSE;
}
}

UINT __stdcall BrowseForFile(MSIHANDLE hInstall)
{
//MessageBox(NULL, "BrowseForFile", "BrowseForFile", MB_OK);

//Set up storage for PATHTOFILE
TCHAR szOriginalPath[MAX_PATH];
DWORD cchValue = sizeof(szOriginalPath)/sizeof(TCHAR);
ZeroMemory(szOriginalPath, sizeof(TCHAR)*MAX_PATH);

// Get PATHTOFILE
MsiGetProperty(hInstall, TEXT("PATHTOFILE"), szOriginalPath, &cchValue);

long lErrMsg = 0;
OPENFILENAME ofn;

ZeroMemory(&ofn, sizeof(ofn));

TCHAR szFilters[] =
_T("All Files (*.*)\0*.*\0")
_T("Text File (*.txt)\0*.txt\0");

// Initialize OPENFILENAME structure.
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetForegroundWindow();
ofn.lpstrFile = szOriginalPath;
ofn.nMaxFile = sizeof(szOriginalPath);
ofn.lpstrFilter = szFilters;
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
//ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
//ofn.Flags = OFN_HIDEREADONLY;

if (GetOpenFileName(&ofn))
{
MsiSetProperty(hInstall, TEXT("PATHTOFILE"), szOriginalPath);

//This next bit of code fixes a problem that occurs if the author is
//using an Edit box for the path. For whatever reason, if a user
//types into the edit box before browsing for a file or folder
//the Edit box is not updated once the custom action completes.
//Much of the following code was modified from
//Kallely L Sajan's IsLicensedViewed article from InstallSite.org
HWND hWnd;
HWND hWndChild=NULL;

hWnd = FindWindow(NULL, "Default - InstallShield Wizard");
if (hWnd) {
EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
if ( hWndChild ) {
TCHAR buf[100];
_tcscpy(buf, szOriginalPath);
//the following call will not work if _UNICODE is defined in Prepocessor definitions
SendMessage(hWndChild, WM_SETTEXT, 0, (LPARAM)szOriginalPath);
}
}
}
return ERROR_SUCCESS;
}[/CODE]


Kind regards,
Peter
Labels (1)
0 Kudos

(8) Replies
RobertDickau
Flexera Alumni

The function prototype (UINT __stdcall BrowseForFile(MSIHANDLE hInstall)) indicates that the function expects to be called from the MSI sequences as an MSI DLL custom action, and not from a script. If you look at www.installsite.org > InstallScript Samples > User Interface, are there InstallScript-friendly versions of the file-browse dialog available?
0 Kudos
blood_on_ice
Level 4

Thanks a lot! This one:

http://www.installsite.org/files/FileBrowseDlg6.zip

helps me solve my problem!

Kind regards,
Peter

RobertDickau wrote:
The function prototype (UINT __stdcall BrowseForFile(MSIHANDLE hInstall)) indicates that the function expects to be called from the MSI sequences as an MSI DLL custom action, and not from a script. If you look at www.installsite.org > InstallScript Samples > User Interface, are there InstallScript-friendly versions of the file-browse dialog available?
0 Kudos
Ray_Portrait
Level 6

I have also downloaded the browseForFile.zip and was wondering what is the best way to set the filter for the type of files that you would like the dialog to use? I want this to be dynamic so that I can use this dll more than once in my projects and with different filters.

I am using Basic MSI project (IS2008, soon to be IS2009). I have tried to use Properties in my IS project that gets sucked up from the dll which I was hoping to be easy enough to do. the only problem is that whatever the property gets set as, it is handled by the dll as a single element of the filter array - thus causing the filter not to work.

I don't know if using properties for the filter is best or if passing parameters to the dll's function would be better (I don't know how to do this in IS).

Please help!!!
0 Kudos
RobertDickau
Flexera Alumni

If you're moving to InstallShield 2009, it has a new file-browse custom action for MSI projects, where you can set the file filters to use in properties called IS_BROWSE_FILEEXT and the like.

I haven't tried it, but if you're going to modify that DLL code for InstallShield 2008, presumably your custom property could store the dynamic extensions you want separated by something like a vertical-bar character, and then have the DLL set up the null characters and array for you...
0 Kudos
Ray_Portrait
Level 6

IS2009 works like a charm!!! This is fantastic news! Thanks Rob D
0 Kudos
Ray_Portrait
Level 6

Ok, in my enthusiasm I didn't notice that the IS_BROWSE_FILEBROWSED property only puts the path of the file down without the file selected. I cloned the DestinationFolder dialog and changed the ChangeFolder button's event as suggested in the IS2009 help file.

How can I set this property to return the path and filename?
0 Kudos
Ray_Portrait
Level 6

found the solution:

On the button that browses in your dialog that launches the FileBrowse Dll MSI Binary CA, you must have 2 events.

1) Event: DoAction, Argument: FileBrowse, Condition: 1
2) Event: [IS_BROWSE_FILEBROWSED], Argument: [PROP_TO_STORE_FILE_TO], Condition: 1

This works with flying colours for me!!!
0 Kudos
Rowshan
Level 2

Hi,

I would like to update three text boxes on my dialog. How can I accomplish this by changing the BrowseForFile.cpp? I am calling the BrowseForFile.DLL via Installshield's custom action and have three additional text boxes (Edit1, Edit2, Edit3).

Note that the problem occurs when I edit the box and then browse to a file which contains values of the text boxes. If I don't edit and browse to the file, sendmessage works just fine. I think the following section needs some changes for additional text boxes:


HWND hWnd;
HWND hWndChild=NULL;

hWnd = FindWindow(NULL, "Default - InstallShield Wizard");
if (hWnd) {
EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
if ( hWndChild ) {
TCHAR buf[100];
_tcscpy(buf, szOriginalPath);
//the following call will not work if _UNICODE is defined in Prepocessor definitions
SendMessage(hWndChild, WM_SETTEXT, 0, (LPARAM)szOriginalPath);
}
}


Thanks,
0 Kudos