mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Remove folder after installation

Hi

So I now have a project which requires me to do multiple custom actions. Namely : use a .net installerclass to change some XML configurations, call a batch file to set a service's Failure Options, and call a batch file to start the service. The goal is to remove all those necessary files after they are used.

So let's go from the beginning. Those actions must all be done after the files are copied on the server, so they cannot be Temporary Files (destroyed too soon), so I add them in a subfolder under the Application Folder. It has the identifier DeploymentItems_Dir and includes the installerclass DLL and the 2 batch files. The custom actions are all called after the Finish Execution stage, so at the very last place I can set them.

My method so far was to add another custom action at the end : execute an inline VB Script. (by the way, is there a way to make it multi-line? I can't add a file in this case because of the very reason I need it, and the custom action editor only seems to allow 1 line.)

Code: Select all

CreateObject("Scripting.FileSystemObject").DeleteFolder "" + Session.Property("DeploymentItems_Dir") + ""
But this code gives a warning saying a part of the installation package did not execute properly (but the installation is not cancelled). After some investigation, I found that, oddly enough, it only deleted 1 of the batch files and left the other files intact. Because if I remove this action, the batch file is not deleted. However, I can't figure out why this happens. My only clue is that the non-deleted files are impossible to delete, as if they were still being used. But the VBS custom action is the very last, and I checked that all my actions have the "Wait for finish before proceeding" box checked. Oh and if I MsgBox the property's value, I do get the full path of the folder as expected. I also tried hardcoding the path, adding and removing quotes or parenthesis, removing the last backslash, nothing helps. And the DeleteFile command fails even on the batch file that gets removed by the DeleteFolder command. If I copy my VBS line (and swap the parameter) into a file on the computer and run that file manually after the installation is done, that works, so the problem really seems to be during the installation.

I have seen multiple articles related to this, usually they call a VB Script file, but we would be stuck in the same problem : I would then need to call another file to delete that script. And I tried the File Operation (delete *.* in that folder) but it gets executed before the files are deployed so that's no use either.

Do you know of a way to do this?
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

Hi,
by the way, is there a way to make it multi-line?
This feature will be available starting with the next version of Advanced Installer (10.1) which will be available very soon.
But this code gives a warning saying a part of the installation package did not execute properly (but the installation is not cancelled).
I'm not sure why you encounter this behavior.
Do you know of a way to do this?
A simple way to achieve this is to create a VBScript file (i.e. the file you said it worked when you ran it manually) and call it in a "Launch attached file" custom action. In this case the VBScript file will be automatically embedded in the MSI as a binary file and will not be copied to the end-user's computer.

Let us know if this helped, otherwise give us more details about your scenario.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

Good news for the multi-line! :)

I encounter this behavior anytime there is an error while executing a VBScript in "Execute Inline Script" custom action. Such as not being able to fully delete a folder using the DeleteFolder function.

I am still currently testing the Launch Attached File custom action as you suggested (getting the correct syntax took a while). But I encountered the same error : only 1 of the files used in the Custom Actions is deleted, there is an error while trying to delete the rest. This delete custom action is the very last. My guess is that somehow the file handles are still not closed properly at that point, except for 1 (which is strange because it's between 2 custom actions which are still "locked"). [S]I'm currently trying to add Wait commands and see if it helps, but we can't keep that for our final solution that's for sure[/S] Even waiting 10 seconds before the delete does not work. [S]Maybe we will be forced to change all those custom actions into ones that auto-delete themselves, for example putting everything into DLLs and use the Launch Attached File custom action[/S] We don't want the Wix Framework on top, so we really want to delete that problematic folder!
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

Hi,

I'm not sure why you encounter this behavior, it is possible that your files to be still in use when the final custom action tries to remove them.

Can you please try to follow the steps below and see if the behavior persists:
- make sure that your custom actions have the "Wait for custom action to finish before proceeding" and "Fail installation if custom action returns an error" options enabled
- right-click on the "Finish Execution" stage, and select "Show Standard Action -> Finish Execution -> InstallExecute" action and "Show Standard Action -> Finish Execution -> InstallFinalize" action
- place all your custom actions between "InstallExecute" and "InstallFinalize" standard actions
- check the "deferred" with "no impersonation" options for the last custom action (the VBS custom action that deletes your folder)
- build and run the project (you can use the "Run and Log" option to see more details about the installation)

Let us know if it worked.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

Thanks for the reply.

So I moved all those custom actions to before InstallFinalize (they used to be after). This let me check the Deferred and No Impersonation boxes for the DeleteFolder custom action. Result : it can't access properties. Well that's no better now. And if I place the DeleteFolder custom action back to after InstallFinalize, even if the custom actions are a step behind it I still get the error. If I place DeleteFolder before InstallFinalize and hardcode the path, I still get the error.
EDIT : and yes, I am 100% sure they all have the Wait/Fail boxes checked under Execution Options.

I'm attaching some screenshots in case it can help. Here is the script I currently use in my DeleteFolder script :

Code: Select all

Function DeleteFolder()
	MsgBox(Session.Property("DeploymentItems_Dir"))
	path = Session.Property("DeploymentItems_Dir")
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set folder = fso.GetFolder(path)
	Set files = folder.Files
	For Each tempFile in files
		fileName = tempFile.Name
		MsgBox("DeletING : " + fileName)
        	tempFile.Delete
		MsgBox("DeletED : " + fileName)
	Next
	folder.Delete
End Function
And it correctly deletes the SetFailureOptions batch file, it tries to delete the installerclass (I get the DeletING messagebox) and then I get the error as seen in the screenshots.

Oh and interesting note : if the DeleteFolder custom action is placed before InstallFinalize and it fails, the error message is slightly different and the installation is rollbacked (it continued if the action was after).

EDIT: oh, interesting. Only the Installerclass file is "locked", if I add a condition to disable its custom action then everything gets deleted correctly... including 2 temp files I did not know about (such as TMP688.tmp) and the InstallState file. And another very interesting test that I just did is that even if I remove all the code in the installerclass' function (it calls an empty function, so it shouldn't get stuck or anything) I still can't delete it. So I'm certain it's not the code inside that causes this, but the very fact that it gets executed.

EDIT2 : I just sent the log to support, in case it helps.
Attachments
Custom actions.zip
screenshots
(74.92 KiB) Downloaded 940 times
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

Hi,

Indeed, it seems like the installer keep the DLL file (used by the .Net Installer Class custom action) in use during the whole process of the installation, and that's why it cannot be deleted by the VBScript custom action.

I tested this scenario with the "DeleteFolder" custom action placed under the "Finish Dialogs Stage" and it worked for me. Can you please test the same scenario and see if the behavior persists?

Otherwise, as a workaround, you can create your DLL as described in the How do I create fully fledged C# custom actions article and use it in a "Launch attached file" custom action where you can choose which function of your DLL to use. In this case the file will not be copied on the end user's machine.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

Thanks for the reply, and for making the VBS multi-line! :)

So I just tried tried putting my DeleteFolder script under the Finish Dialogs Stage (I didn't know that was possible, it didn't seem to work the first time I tried it). Unfortunately, I still get the exact same error. And the Deferred/No Impersonation boxes are disabled. Also, we said no to Wix, so no "fully fledged custom actions". I actually had the idea to transform my installerclass into a DLL some time back but stopped because of the Wix prerequisite.

I'll run some more tests (I now have more projects that need the same DeleteFolder scripting) and look for more workarounds, see if it's possible somehow.
EDIT : the error happens in all my projects in which I tried to delete the Deployment Items folder (with installerclass in it) using VBS.
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

Hi,

I'm not sure why have you "stopped because of the Wix prerequisite". The WiX Toolset should be installed only on your machine, you don't need to add it as a prerequisite in your installation package.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

I meant the prerequisite of installing and using Wix in order to create the setup. We don't want Wix.
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

Still no new ideas? Should I try sending logs and VS solutions demonstrating that it didn't work for me even after putting the DeleteFolder custom action after the Finish Dialogs Stage? Should I continue looking for more creative solutions (no Wix)? The only one I have right now is creating a scheduled task will trigger after install to go delete the installerclass DLL, I'd very much like to avoid having to do that.
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

Hi,

After more investigation, I found the following limitation:
- the ".NET InstallerClass" file is kept in use by the installer during "Install Execution Stage" action group and that's why it cannot be deleted
- in this case the file can be deleted only after "Finish Dialogs Stage" action group
- if the file is created in "[ProgramFilesFolder]\..." you need administrator privileges to delete it

Taking these limitations into account, I found two workarounds:
1. Go in the Install Parameters page and check the "Run as administrator" option (in this case you will have an EXE package instead of MSI), then place your VBScript custom action after the "Finish Dialogs Stage" action group

OR

2. Set the path for your "DeploymentItems_Dir" folder so that it does not require administrator privileges (i.e. "C:\folder"), then place your VBScript custom action after the "Finish Dialogs Stage" action group

I tested both scenarios and they worked well to me.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
mstarnaud
Posts: 45
Joined: Mon Apr 15, 2013 9:44 pm

Re: Remove folder after installation

Sorry for the wait, I had to try some other features as well.
After more investigation, I found the following limitation:
- the ".NET InstallerClass" file is kept in use by the installer during "Install Execution Stage" action group and that's why it cannot be deleted
- in this case the file can be deleted only after "Finish Dialogs Stage" action group
- if the file is created in "[ProgramFilesFolder]\..." you need administrator privileges to delete it
This looks very helpful and I'm thankful... but it's contradictory to all my findings so far. I have :
- still in use in the Finish Dialogs stage (or at least, I can't delete it at that point).
- I can delete all other files in the same folder, even if it's Program Files and even if they're used after the installerclass, like my Start Service batch file. Buuuuuut... see below.
1. Go in the Install Parameters page and check the "Run as administrator" option (in this case you will have an EXE package instead of MSI), then place your VBScript custom action after the "Finish Dialogs Stage" action group
Nope, didn't work :( Although the only configuration I tried so far is with the InstallerClass as Deferred/No Impersonation and the DeleteFolder as Immediate.
2. Set the path for your "DeploymentItems_Dir" folder so that it does not require administrator privileges (i.e. "C:\folder"), then place your VBScript custom action after the "Finish Dialogs Stage" action group
Yes! Finally, it works somehow! I currently still have the EXE Run As Admin configuration from my last tries, and deploying to C/Temp/ProgramName. More testing needed to see how much flexibility I have over this.

So the big breakthrough I was waiting for, thanks a lot for the help! Will post again if I get more details on this.

EDIT1 : so it worked, I started playing with some settings and could only reproduce it randomly. Found cause #1 for not working : I ask the user for a property (textbox) and in a SetProperty action I set it to empty {} before the dialog. If the user leaves it empty, for some reason my folder was not deployed at all and the script crashed. Weird. But beside that, there still seems to be something totally random that makes this fail : it works, I change an option, it crashes, I set it back, it still crashes. This seems to happen mostly with Install Parameter : Fast Installation.

EDIT2 : something at runtime seems to affect this somehow. If I have a working EXE and keep it, create a new EXE that fails, and re-run the first EXE, it will now fail instead of succeeding again. I have no idea what's going on. I did find that failed installers sometimes stay opened in the task manager (msiexec) which keeps the files locked, but I go delete them every time. I also noticed the EXE's size randomly changes between 1.8M and 2.3M -EDIT- that's most likely the encryption which changes when you play with the Fast Installation option.

EDIT3 : still randomly quirky. Just did a test that used the Program Files folder and the file was deleted successfully, which contradicts the reason for the first successes ([ProgramFilesFolder]\[Manufacturer]\[ProductName]). Totally expected that to fail. Still don't understand what's going on. On another note, I'm now suspecting the Media window's encryption (LZMA vs CAB) might be up to something, I think it changes sometimes with the Fast Installation and other options. Oh and I had some successes without Run As Admin too, but never with MSIs. Still investigating. Oh and sometimes I can set the DeleteFolder action to Deferred, sometimes it's disabled and I can only choose Immediately. Weird.

EDIT4 : Required : EXE output file, Fast Installation (Install parameters window), CAB encryption (Media window), action must be in Finish Dialogs and Immediate. My Installerclass action is Deferred with No Impersonation. And if you change any of those, it's very possible that even if you put those options back it still won't work. If that happens, try checking-unchecking options or closing AI and restarting it. I don't know why that "playing around" is needed. Oh, and don't forget to not leave any property empty (see comment in EDIT1 section).
Last edited by mstarnaud on Tue May 14, 2013 8:03 pm, edited 11 times in total.
Eusebiu
Posts: 4959
Joined: Wed Nov 14, 2012 2:04 pm

Re: Remove folder after installation

You're welcome. I'm glad you got this working.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Building Installers”