cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
InstallGal
Level 3

Expanding Environment Variables

Hello,

During a silent install the user passes env variables to the Basic MSI installer.
Using a custom script I try to expand it using the following code:

prototype stdcall NUMBER Kernel32.ExpandEnvironmentStrings(BYVAL STRING, POINTER, NUMBER);
....
....
pString = &svCacheRootExpanded;
nvSize = 256;

MsiGetProperty (hMSI, "CACHE_ROOT", svCacheRoot, nvSize);
MsiGetProperty (hMSI, "INSTALLDIR", svInstallDir, nvSize);

if (svCacheRoot == "") then
svCacheRoot = svInstallDir + "Cache";
MsiSetProperty(hMSI, "CACHE_ROOT", svCacheRoot);
else
intRetval =Kernel32.ExpandEnvironmentStrings(svCacheRoot,pString, nvSize);
SprintfBox (INFORMATION, "return value ", "retval: %d", intRetval);
MessageBox ("path: " + svCacheRoot, SEVERE);
MessageBox ("expanded path: " + svCacheRootExpanded, SEVERE);
endif;
intRetval is 37
svCacheRoot is %VAR%
svCacheRootExpanded is empty

Any ideas why the svCacheRootExpanded does not get the value of the expanded path?

Thanks,
Bila
Labels (1)
0 Kudos
(9) Replies
RobertDickau
Flexera Alumni

Could it be that the destination buffer size nvSize is too small (shorter than the 37 chars indicated in the return value)? Does anything change if you reset nvSize=256 (or whatever pString can hold) before calling ExpandEnvironmentStrings?
0 Kudos
InstallGal
Level 3

After some more investigation it seems that this issue occurs whenever I call
MsiGetProperty (hMSI, "CACHE_ROOT", svCacheRoot, nvSize); The svCacheRoot is set by the user in a silent install batch script.

If I remove the above call and hardcode svCacheRoot inside the script (ie. svCacheRoot="%USERPROFILE%" ) the call returns the correctly expanded string.

I could reproduce this even when I changed the way I call the function to:


prototype INT kernel32.ExpandEnvironmentStringsA(BYVAL STRING, BYREF STRING, INT);
export prototype ExFn_CreateCacheDir(HWND);
function ExFn_CreateCacheDir(hMSI)

STRING svCacheRoot, svCacheRootExpanded, svUILevel;
NUMBER nvSize;
INT intRetval;
STRING svEnvVar;
STRING svInstallDir;
STRING svCantSaveFilesHere;


begin

nvSize = 256;
MsiGetProperty (hMSI, "CACHE_ROOT", svCacheRoot, nvSize);
intRetval = ExpandEnvironmentStringsA( svCacheRoot, svCacheRootExpanded, nvSize);
MessageBox(svCacheRootExpanded,0);
SprintfBox (INFORMATION, "return value ", "retval: %d", intRetval);
MessageBox ("path: '" + svCacheRoot + "'", SEVERE);
MessageBox ("expanded path: " + svCacheRootExpanded, SEVERE);



Thanks,
Bila
0 Kudos
RobertDickau
Flexera Alumni

How does the silent install batch script script set %CACHE_ROOT% or CACHE_ROOT?
0 Kudos
InstallGal
Level 3

I've tried both with the same result:

Setup.exe /s /v"/qn" /v"INSTALLDIR=\"C:\Program Files\Documentum\FSS\"" /v"CACHE_ROOT=%%USERPROFILE%%" /v"CS_ENABLE=FALSE" /v"CS_SERVER_URL=\"\"" /v"FSS_ABBREVIATEDPRODUCTNAME=MDD" /v"FSS_BROWSE_CACHE_TIMEOUT=120000" /v"FSS_CACHE_CLEANUP_CRON_SCHEDULE=\"0 0 2 * * ?\"" /v"FSS_CACHE_CLEANUP_QUOTA=20Mb" /v"FSS_DEFAULT_CABINET_OBJECT_TYPE=dm_cabinet" /v"FSS_DEFAULT_DOCUMENT_OBJECT_TYPE=dm_document" /v"FSS_DEFAULT_FOLDER_OBJECT_TYPE=dm_folder" /v"FSS_DEFAULT_REPO=\"\"" /v" FSS_DOMAIN=EARTH" /v"FSS_IGNORE_HOST_WARNING=false" /v"FSS_MONITOR_SHUTDOWN_TIMEOUT=60" /v"FSS_OFFLINE_CHECK_INTERVAL=30s" /v"FSS_OFFLINE_TIMEOUT=30s" /v"FSS_PORT=4545" /v"FSS_REQUESTED_ATTRIBUTES=\"r_object_type,r_content_size,r_modify_date,r_creation_date\"" /v"FSS_RETAIN_CACHE=TRUE" /v"FSS_SCHED_IMPORT_ENABLED=FALSE" /v"FSS_SCHED_IMPORT_TIME=15m" /v"FSS_SERVER_URL=\"http://torontario:8890\"" /v"FSS_TASKPANE_ATTRIBUTES=\"object_name,r_object_type,r_content_size,r_modify_date,r_creation_date\"" /v"FSS_USE_ACS_DIRECTLY=FALSE" /v"FSS_WS_TIMEOUT_FILEOPS=30000" /v"FSS_XMLRPC_PORT=2736" /v"/l*v MDD.log"

And

Setup.exe /s /v"/qn" /v"INSTALLDIR=\"C:\Program Files\Documentum\FSS\"" /v"CACHE_ROOT=\"%%USERPROFILE%%\"" /v"CS_ENABLE=FALSE" /v"CS_SERVER_URL=\"\"" /v"FSS_ABBREVIATEDPRODUCTNAME=MDD" /v"FSS_BROWSE_CACHE_TIMEOUT=120000" /v"FSS_CACHE_CLEANUP_CRON_SCHEDULE=\"0 0 2 * * ?\"" /v"FSS_CACHE_CLEANUP_QUOTA=20Mb" /v"FSS_DEFAULT_CABINET_OBJECT_TYPE=dm_cabinet" /v"FSS_DEFAULT_DOCUMENT_OBJECT_TYPE=dm_document" /v"FSS_DEFAULT_FOLDER_OBJECT_TYPE=dm_folder" /v"FSS_DEFAULT_REPO=\"\"" /v" FSS_DOMAIN=EARTH" /v"FSS_IGNORE_HOST_WARNING=false" /v"FSS_MONITOR_SHUTDOWN_TIMEOUT=60" /v"FSS_OFFLINE_CHECK_INTERVAL=30s" /v"FSS_OFFLINE_TIMEOUT=30s" /v"FSS_PORT=4545" /v"FSS_REQUESTED_ATTRIBUTES=\"r_object_type,r_content_size,r_modify_date,r_creation_date\"" /v"FSS_RETAIN_CACHE=TRUE" /v"FSS_SCHED_IMPORT_ENABLED=FALSE" /v"FSS_SCHED_IMPORT_TIME=15m" /v"FSS_SERVER_URL=\"http://torontario:8890\"" /v"FSS_TASKPANE_ATTRIBUTES=\"object_name,r_object_type,r_content_size,r_modify_date,r_creation_date\"" /v"FSS_USE_ACS_DIRECTLY=FALSE" /v"FSS_WS_TIMEOUT_FILEOPS=30000" /v"FSS_XMLRPC_PORT=2736" /v"/l*v MDD.log"
0 Kudos
RobertDickau
Flexera Alumni

Hmm, a simplified similar example seems to work for me... InstallScript code is:
#include "ifx.h"

prototype Kernel32.ExpandEnvironmentStringsA(BYVAL STRING, BYREF STRING, INT);

export prototype exp(HWND);

function exp(hInstall)
NUMBER nvSize;
STRING svRawCacheRoot, svExpandedCacheRoot;
INT ret;
begin

// raw value from command line
nvSize = MAX_PATH;
MsiGetProperty(hInstall, "CACHE_ROOT", svRawCacheRoot, nvSize);

MessageBox("CACHE_ROOT: " + svRawCacheRoot, INFORMATION);

// expanded value from API
nvSize = MAX_PATH;
ret = ExpandEnvironmentStringsA(svRawCacheRoot, svExpandedCacheRoot, nvSize);

SprintfBox(
INFORMATION, "Expanded?", "ret = %d;\nsvExpanded... = %s",
ret, svExpandedCacheRoot);

return ERROR_SUCCESS;

end;

Custom action is immediate mode, just after AppSearch.

Launching setup.exe with batch file containing:
setup.exe /V"CACHE_ROOT=%%JAVA_HOME%%"

At run time, first message box correctly shows:
CACHE_ROOT: %JAVA_HOME%

Second shows:
ret = 34;
svExpanded... = C:\Program Files\Java\jdk1.6.0_18
InstallGal
Level 3

What are you setting MAX_PATH to be?

Why can't nvSize be hardcoded inside the function to say nvSize=256 since we don't expect the path to be longer than 256 characters?

Thanks,
Bila
0 Kudos
RobertDickau
Flexera Alumni

MAX_PATH is a predefined constant (with value 260 or so); I just used it out of habit, and the example seems to run unchanged with a hard-coded nvSize of 256.
0 Kudos
InstallGal
Level 3

Thanks for your help. Looks like I forgot to reset nvSize after the MsiGetProperty call and before the ExpandEnvironmentStringsA call.

Bila
0 Kudos
RobertDickau
Flexera Alumni

Good news---thanks for posting the follow-up.

Robert
0 Kudos