PDA

View Full Version : Major problem with CSIDL_COMMON_DOCUMENTS



LanceRas
06-05-2007, 08:04 PM
Unless I'm missing something, there is still not a default directory for All Users > Documents. For Vista, it would be C:\Users\Public\Documents

I've got an IS12 Pro project that has this as a custom action set to execute after CostInitialize:

function GetCommonDocuments(hMSI)
// To Do: Declare local variables.
STRING svPath,svPrevApp, svSystemFolder, svCommonDocuments, svVersionNumber;

NUMBER nvFolder, nvSize, nvResult;
begin
// nvSize = 256;
// MsiGetProperty (ISMSI_HANDLE, "SystemFolder", svSystemFolder, nvSize);
// MessageBox("0) svSystemFolder " + svSystemFolder, INFORMATION);

try
nvFolder=CSIDL_COMMON_DOCUMENTS;
svPath="";
svCommonDocuments="";
nvResult=SHFolder.SHGetFolderPathA(NULL, nvFolder, NULL, 0, svPath);
if (nvResult=0) then
// MessageBox("CSIDL_COMMON_DOCUMENTS= " + svPath,0);
svCommonDocuments=svPath;
else
SprintfBox(SEVERE, "CSIDL_COMMON_DOCUMENTS", "Failed(%d): %s", nvResult, FormatMessage(nvResult));
endif;
catch
MessageBox("Unsupported OS.",0);
endcatch;

MsiSetProperty (ISMSI_HANDLE, "CommonDocsAll", svCommonDocuments);
MsiSetProperty (ISMSI_HANDLE, "COMMONDOCSALL", svCommonDocuments);
MsiSetProperty (ISMSI_HANDLE, "COMMONDOCSALL1", svCommonDocuments);

MsiSetTargetPath(hMSI, "CommonDocsAll", svCommonDocuments);
MsiSetTargetPath(hMSI, "COMMONDOCSALL", svCommonDocuments);
MsiSetTargetPath(hMSI, "COMMONDOCSALL1", svCommonDocuments);


MessageBox("COMMON_DOCUMENTS= " + svCommonDocuments, INFORMATION);
end;



I've set the Directory name to CommonDocsAll.

This works properly.

When I created a new IS2008 project, I attempted to do the same thing and it would not create the directory inside the Public Documents. So I copied the IS12 project to IS2008, converted it. Ran it. It creates it fine.

Suggestions, workarounds are welcome.

I'm simply trying to set this path to nest files during installation.

rchand445
06-06-2007, 12:34 PM
It appears that CSIDL constants are depreciated on Vista. This operating system returns common folder locations using Known Folder ID's and the shell32 function SHGetKnownFolderPath, which is new with Vista. You would need to pass the Known Folder ID FOLDERID_PublicDocuments. More information can be found in Microsoft's MSDN library: Known Folders (http://msdn2.microsoft.com/en-us/library/aa969404.aspx), SHGetKnownFolderPath Function (http://msdn2.microsoft.com/en-us/library/ms647783.aspx) and KNOWNFOLDERID (http://msdn2.microsoft.com/en-us/library/bb407328.aspx)

I haven't been working with Installscript functions for some time - but I'm guessing that you would need to define the prototype for SHGetKnownFolderPath in your script before referencing it.

LanceRas
06-06-2007, 03:37 PM
I now have it resolved. I ended up calling support, but wanted to post my findings.

Below is the modified function. It has to be called after CostFinalize and not CostInitialize.

Lance


=========================================

// Define Microsoft CSIDL constants
#define CSIDL_COMMON_DOCUMENTS 0x002e

// Prototype SHGetFolderPath in shell32.dll
prototype NUMBER shell32.SHGetFolderPath(HWND, INT, NUMBER , NUMBER, BYREF STRING);
// Prototype SHGetFolderPathA in SHFolder.dll
prototype NUMBER SHFolder.SHGetFolderPathA(HWND, NUMBER, NUMBER, NUMBER, BYREF STRING);



function GetCommonDocuments(hMSI)
// To Do: Declare local variables.
STRING svPath,svPrevApp, svSystemFolder, svCommonDocuments, svVersionNumber;

NUMBER nvFolder, nvSize, nvResult;
begin

// Need to make sure that this is called in CostFinalize for custom action.
try
nvFolder=CSIDL_COMMON_DOCUMENTS;
svPath="";
svCommonDocuments="";
nvResult=SHFolder.SHGetFolderPathA(NULL, nvFolder, NULL, 0, svPath);
if (nvResult=0) then
svCommonDocuments=svPath;
else
SprintfBox(SEVERE, "CSIDL_COMMON_DOCUMENTS", "Failed(%d): %s", nvResult, FormatMessage(nvResult));
endif;
catch
MessageBox("Unsupported OS.",0);
endcatch;

MsiSetTargetPath(hMSI, "CommonDocsAll", svCommonDocuments);
end;

gridman
09-09-2007, 10:01 AM
There is a part of this I don't understand.

If you write the custom action as you have outlined, then you also have to define an entry in the Directory table for CommonDocsAll? Because that entry doesn't exist there to begin with? If that's correct, you would then refer to the CommonDocsAll path in all the places you need it during your install. Correct?

The other question is, would this custom action be called after CostFinalize in the Execute sequence?