I have a setup that is installing a PDF program. It works perfectly on test machines. When there is other PDF software on the machine, errors pop up because of the large number of shared files that are inuse.
Inno has the /SUPPRESSMSGBOXES option. However I can not seem to configure this to ignore the file copy - it either wants to Abort or Retry. Abort - the setup will fail. Retry - will never succeed because the file is in use.
Does anyone know how to automatically ignore any copy file errors while setting up?
You can use the restartreplace flag for the files that may be in use, it is exactly to suppress those error dialogs.
To quote the documentation of the [Files] section:
restartreplace
When an existing file needs to be replaced, and it is in use (locked) by another running process, Setup will by default display an error message. This flag tells Setup to instead register the file to be replaced the next time the system is restarted (by calling MoveFileEx or by creating an entry in WININIT.INI). When this happens, the user will be prompted to restart their computer at the end of the installation process.
Related
I am using NSIS to write an installer for my windows application. After installing the application, an uninst.exe is also generated in my program directory. Later on I need to uninstall my program but I failed to do that in control panel. Therefore I went to the file system and tried to delete the directory. Everything other than that uninst.exe was removed. I've tried changing permission of this file and other methods but it doesn't work.
WriteUninstaller does not set file permissions or any other attribute that might prevent you from deleting it. It sounds like the file might still be in use by something on your machine.
Things to try:
Use Task Manager or Process Explorer to see if there is a uninst.exe process still running.
Use the find handle feature in Process Explorer to find any open handles to the file.
Use Process Monitor to get detailed information about the failed delete operation.
Check %LOCALAPPDATA%\VirtualStore to make sure UAC Virtualization is not tricking you with "ghost" files.
Disable your Anti-Virus.
Reboot the machine and try to delete the file again.
I have an application installer created with Inno Setup that deploys multiple binaries and support files for my application.
When I perform an upgrade installation (e.g. run setup-1.5.exe while version 1.0 is already installed), some of the files from the previous version are frequently in-use, and cannot be replaced until the next reboot. That is fine, Inno handles that case correctly.
However, the logic I really want is: if any files cannot be replaced until the next reboot, then I want all files to be replaced on the next reboot. Otherwise, binaries that are in use are not replaced but some support files might be, leaving the application in an unstable state prior to reboot anyway.
Is there a clean way to accomplish this? I have not been able to find one, short of locking all the support files myself explicitly, which is quite ugly.
Thanks!
Inno can't do this natively. This is why it provide AppMutex and friends to ensure that it's all clear, and if anything is left, it tells the user that they must reboot.
You can then expand on this in your app and refuse to start if a restart replace action is pending.
My setupper gives the ERROR access denied dialog when overwriting one DLL fails,
its locked&in use sometimes.
what is recommended procedure for doing this..
Can I somehow make INNO to compare if its even necessary to overwrite this DLL (size match?)
InnoSetup automatically compares the files to see if it needs to be replaced by looking at the version resource in the file.
You should add the RestartReplace flag to the [Files] entry for your DLL (and any other file that might be in memory / locked). From the InnoSetup documentation:
restartreplace
When an existing file needs to be
replaced, and it is in use (locked) by
another running process, Setup will by
default display an error message. This
flag tells Setup to instead register
the file to be replaced the next time
the system is restarted (by calling
MoveFileEx or by creating an entry in
WININIT.INI). When this happens, the
user will be prompted to restart their
computer at the end of the
installation process.
To maintain compatibility with Windows
95/98/Me, long filenames should not be
used on entries with this flag. Only
"8.3" filenames are supported.
(Windows NT platforms do not have this
limitation.)
NOTE: This flag has no effect on
Windows NT platforms if the user does
not have administrative privileges.
Therefore, when using this flag, it is
recommended that you leave the
PrivilegesRequired [Setup] section
directive at the default setting of
admin.
I want to delete a folder which contains the currently running application. How can i do it..? is there any way of doing it ? i.e the folder which contains the application should delete after the application has finished running ?
Your best bet is probably to use the Win32 API MoveFileEx. It has a flag that can be set for deleting files when they are in use on the next reboot called MOVEFILE_DELAY_UNTIL_REBOOT. Set the new filename parameter of MoveFileEx to NULL to perform this type of delete.
If dwFlags specifies
MOVEFILE_DELAY_UNTIL_REBOOT and
lpNewFileName is NULL, MoveFileEx
registers the lpExistingFileName file
to be deleted when the system
restarts.
Note: Normal files that are in use can be deleted normally using the Win32 API DeleteFile depending on if they were opened (Using the Win32 API CreateFile) with FILE_SHARE_DELETE permission. I don't think running programs by default on Windows have that permission though. When a file is specified to be deleted that is in use but that was opened with this flag, then the file will be removed when the last file handle is closed.
This is hairy. I had to implement this once for a self-patching app, where the patcher had to (by client request) delete itself after installing the patch. You can do this by launching a helper DLL which deletes your process, along with itself.
The full method for deleting your process can be found here: http://www.handcraftedbytes.com/articles/writing-install-and-uninstall
As others have pointed out, you're not going to be able to delete the folder that your executable resides in while it exists there. My suggestion is to:
Use MoveFileEx to move your executable off to a temporary directory,
delete your application's directory,
delete your executable using the self-deleting DLL method described in the link above.
You cannot delete an executable file that is currently running, however you can delete a batch file that is currently running (cmd.exe loads the whole file into memory and then you can delete it).
So the simplest solution would be to launch a batch that tries to delete the .exe in a loop (because it may not work the first time - until your .exe has been unloaded) and then exit your process - with the batch file still running.
On some of the devices that I am working on, the \Windows directory is not on permanent storage. That is, once the device is rebooted, whatever was written to \Windows is lost. This is particularly problematic for uninstalling programs since wceload.exe (the Windows CE CAB installer program) generates a .unload file and places it in \Windows. The application can be uninstalled before the device is rebooted, but afterward it can't (the "Remove Programs" tool in the control panel comes back with an error about not being able to open the unload file). So how can I get the .unload file to persist across reboots? Is there any way to control where the uninstaller (I believe it is called unload.exe) looks for the .unload file?
I haven't been able to find any good info on this still. It looks like the path to the unload file is hardcoded so the best I can do is make a backup of the unload file. If the user wishes to uninstall they will have to manually copy the file to the \windows directory and then use the uninstall tool in the control panel. Here is more info:
http://www.generation-nt.com/us/answer/wince5-force-wceload-install-unload-into-nonvolatile-memory-help-87676002.html
You can probably keep the .unload file across reboots by copying it to a persistent directory after installing. This directory may vary per device, e.g. \Hard Disk\ramroot\Windows or \Backup\Windows. It will then automatically be copied to the \Windows on reboot. (Although I am not sure whether such a directory and behavior exist for every device.)
To copy this file you need to execute a copy-statement from a custom setup-dll after the install completes. This codeproject-site has a very comprehensive explanation, with screenshots and code.
Simply re-Install application and then un-install from remove programs in control panel.