Recent

Author Topic: Deleting exe-file not working anymore in Windows 11  (Read 520 times)

JanRoza

  • Hero Member
  • *****
  • Posts: 693
    • http://www.silentwings.nl
Deleting exe-file not working anymore in Windows 11
« on: September 06, 2024, 01:58:47 am »
I have a program that has been doing its job perfectly under Windows until I migrated to Windows 11.
It is a small secondary program that checks if the main program has been closed and then renames the old main program and after that renames the new downloaded program file to the original programs name. This has been working under all versions of Windows but fails to delete the old main program in Windows 11.
Has anyone experienced the same or know how to improve the code I use for this operation?

Code: Pascal  [Select][+][-]
  1.   // Wait until GliderMaintenance is closed
  2.   while (GmIsRunning(strProgram) <> 0) do bActive := True;  // GliderMaintenance.exe
  3.  
  4.   // Delete archived previous version
  5.   DeleteFile(PChar(strOldProgram));    // GliderMaintenance-old.exe     «-------- This fails in Windows 11
  6.  
  7.   // Rename current main program to old and after that rename new main version to current name
  8.   if RenameFile(strProgram, strOldProgram)             // GliderMaintenance.exe -> GliderMaintenance-old.exe
  9.   then RenameFile(strNewProgram, strProgram);     // GliderMaintenance.new -> GliderMaintenance.exe
  10.  
  11.   // Start new version of GliderMaintenance
  12.   ShellExecute(Handle, 'open', PChar(strProgram), nil, nil, 1);
  13.  
  14.   // Close this update program
  15.   Close;
  16.  


OS: Windows 11 / Linux Mint 22
       Lazarus 3.6 FPC 3.2.2
       CodeTyphon 8.50 FPC 3.3.1

Wallaby

  • Jr. Member
  • **
  • Posts: 96
Re: Deleting exe-file not working anymore in Windows 11
« Reply #1 on: September 06, 2024, 03:47:58 am »
Depending on how you check if it's running, this code is bad for two reasons:

1) Consuming CPU for no reason for repeated checks (can be thousands per second!)
2) A race condition is possible where your code thinks it's not running, but Windows hasn't finishing unloading and releasing the file

Do this instead:

Code: Pascal  [Select][+][-]
  1. while FileExists(strOldProgram) and (not DeleteFile(PChar(strOldProgram))) do Sleep(100); // This will not proceed until the program is closed.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11758
  • FPC developer.
Re: Deleting exe-file not working anymore in Windows 11
« Reply #2 on: September 06, 2024, 09:34:15 am »
This is fairly typical, and not windows 11 specific, e.g. an antivirus can keep the file locked. Or a second instance could be launched(e.g. in an elevated context).

Solution is simple, rename to old<x> after a timeout, and check on startup if files need deleting. (could be a problem if it is in an elevated directory though)

JanRoza

  • Hero Member
  • *****
  • Posts: 693
    • http://www.silentwings.nl
Re: Deleting exe-file not working anymore in Windows 11
« Reply #3 on: September 07, 2024, 12:39:42 am »
I'm pretty sure that the main program is not running as the 'GmIsRunning(strProgram) <> 0' loop is ended (without any noticable delay). Also this code is running for more than 10 years in all previous versions of Windows and never failed me once.
The problem is that the DeleteFile works in Windows < version 11 and does not work in Windows 11.
I will try Wallaby's suggestion as well and see if it solves my problem, I will let you know the result.
OS: Windows 11 / Linux Mint 22
       Lazarus 3.6 FPC 3.2.2
       CodeTyphon 8.50 FPC 3.3.1

JanRoza

  • Hero Member
  • *****
  • Posts: 693
    • http://www.silentwings.nl
[Solved] Deleting exe-file not working anymore in Windows 11
« Reply #4 on: September 07, 2024, 12:57:37 am »
Guys, thanks for your advice, they were useful.
But the real cause was me myself, I was dumb enough to forget to put the new main program version on the server.  :-[
So the process was still working but it updated the main program with the same version instead of the next version, so right after updating and restarting the main program it again showed the message that there was a new version available and asked me if I wanted to update.
So apologies for my stupidity and I will try to be more awake next time.  >:D
OS: Windows 11 / Linux Mint 22
       Lazarus 3.6 FPC 3.2.2
       CodeTyphon 8.50 FPC 3.3.1

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1408
    • Lebeau Software
Re: Deleting exe-file not working anymore in Windows 11
« Reply #5 on: September 07, 2024, 08:37:49 pm »
Some small nitpicks:

Code: Pascal  [Select][+][-]
  1. // Wait until GliderMaintenance is closed
  2. while (GmIsRunning(strProgram) <> 0) do bActive := True;  // GliderMaintenance.exe

This is a busy loop that eats up CPU cycles. At least put a small sleep in the loop to yield cycles.

A better option would be to open a handle to the process if it is running, and then wait on the handle to be signaled when the process exits.  That way, the wait can sleep the entire time the handle is unsignaled.

Code: Pascal  [Select][+][-]
  1. // Delete archived previous version
  2. DeleteFile(PChar(strOldProgram));    // GliderMaintenance-old.exe     «-------- This fails in Windows 11

What is the error code when that happens?  From your latest update, it was probably 2 (ERROR_FILE_NOT_FOUND).  Always check error codes when making system calls!

Code: Pascal  [Select][+][-]
  1. // Rename current main program to old and after that rename new main version to current name
  2. if RenameFile(strProgram, strOldProgram)             // GliderMaintenance.exe -> GliderMaintenance-old.exe
  3. then RenameFile(strNewProgram, strProgram);     // GliderMaintenance.new -> GliderMaintenance.exe

You should consider using the Win32 ReplaceFile() function instead, eg:

Code: [Select]
ReplaceFile(PChar(strProgram), PChar(strNewProgram), PChar(strOldProgram), 0, nil, nil);
Code: Pascal  [Select][+][-]
  1. // Start new version of GliderMaintenance
  2. ShellExecute(Handle, 'open', PChar(strProgram), nil, nil, 1);

You should be using CreateProcess() instead. ShellExecute() is just going to call it anyway, so you can cut out the middle-man.  Yes, it is slightly more code to use CreateProcess(), but it is less overhead to avoid invoking the Shell.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

JanRoza

  • Hero Member
  • *****
  • Posts: 693
    • http://www.silentwings.nl
Re: Deleting exe-file not working anymore in Windows 11
« Reply #6 on: September 07, 2024, 09:28:06 pm »
Thanks for the tips Remy, I will streamline things following your advice and test how that will work out.
OS: Windows 11 / Linux Mint 22
       Lazarus 3.6 FPC 3.2.2
       CodeTyphon 8.50 FPC 3.3.1

 

TinyPortal © 2005-2018