Friday, August 1, 2008

InstallShield LaunchAppAndWait and File Access

The Task: Grant access to the files I have installed to the users I have created.

In the Files & Folders view, you can right click on a folder and select properties to get access to the permissions for a file or folder. However, this doesn't work so well because you can't add permissions to a file, you can only replace them. I didn't want that as I didn't want to clear out the Administrators group access to my install folder. I just wanted to add a couple of users to the access list. The real answer is to use LaunchAppAndWait to run cacls.exe on the folder.

I have used LaunchAppAndWait in the past and have struggled with it. It is difficult to debug. So, there are some things I would recommend. First, add a MessageBox for debug that shows what you are going to run. If you are not getting desired results, copy exactly what is in your message into a console window on the target system with your files in place and see what happens. You might be surprised. LaunchAppAndWait tells you if it launched the program, but does not tell your if the program had errors.

Of course, that isn't the way I did it the first time. The first time I was convinced LaunchAppAndWait was messing up. So, I created a sanity-check app in Visual Studio and called it from LaunchAppAndWait.



It's very simple. Take the arguments from the command line and put them into a text file. This way, you can use whatever command parameters your real command needs. Just change the program to the test app.

To use LaunchAppAndWait, set up a variable for the program name and a variable for the parameters. Actually, here is my function.

function SetDirectoryPermissions(szDirectoryName, szUserName)
STRING szProgName;
STRING szProgParams;
STRING svTempString;
begin
// Remove any trailing slash from the directory name.
StrSub(svTempString, szDirectoryName, StrLength(szDirectoryName) - 1, 1);
if (svTempString = "\\") then
StrSub(svTempString, szDirectoryName, 0, StrLength(szDirectoryName) - 1);
szDirectoryName = svTempString;
endif;

szProgName = WINDIR^"system32\\cacls.exe";
szProgParams = " " + szDirectoryName + " /E /G " + szUserName + ":F";
if (LaunchAppAndWait(szProgName, szProgParams, WAIT) <>
MessageBox("Unable to launch cacls. File permissions will need to be set manually.", WARNING);
endif;
end;


With all that out there in the open, it shows the issue I had with cacls.exe. If you pass in INSTALLDIR, there is a trailing slash (IS always puts one there). cacls.exe throws an error saying that it can't find the file. So, I had to remove the trailing slash and IT WORKED!

BTW, the command it is running is

cacls.exe C:\InstallDir /e /g DOMAIN\USER:F

Which brings up my last point. You should include the domain with the user name. Windows needs that to properly locate the credentials for the user.

Ok, so my code samples are rough. I am still getting used to blogger.

1 comment:

Anonymous said...

Thanks for posting this. It was exactly what I was looking for to set permissions during installation -- which has gotten a lot more important in Windows 7.