From d187f119ebe3b70a5a990ccc1a9b575245d0c2ac Mon Sep 17 00:00:00 2001 From: Dom Slee Date: Sat, 18 May 2024 19:18:38 +1000 Subject: [PATCH] Update to use .net8, and change defaults --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/ci.yaml | 2 +- .github/workflows/release.yaml | 2 +- Directory.Build.props | 4 +-- .../src/ForceOpsContext/ForceOpsContext.cs | 4 +-- .../src/FileAndDirectoryDeleterTest.cs | 16 ++++----- ForceOps/src/ForceOps.cs | 4 +-- README.md | 34 ++++++++++++------- 8 files changed, 39 insertions(+), 29 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index c757574..95844d7 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -19,7 +19,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-dotnet@v3 with: - dotnet-version: '7.0.x' + dotnet-version: '8.0.x' - name: Build Deps run: | cd subrepos/LockCheck; diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e67006c..0662384 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,7 +23,7 @@ jobs: - name: Install Dotnet uses: actions/setup-dotnet@v3 with: - dotnet-version: "7.0.x" + dotnet-version: "8.0.x" - name: Dotnet Installation Info run: dotnet --info diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b9129a7..7c6afae 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -36,7 +36,7 @@ jobs: - name: Install Dotnet uses: actions/setup-dotnet@v3 with: - dotnet-version: "7.0.x" + dotnet-version: "8.0.x" - name: Directory structure run: | diff --git a/Directory.Build.props b/Directory.Build.props index c28fec0..004c7ec 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ By hook or by crook, perform operations on files and directories. If they are in use by a process, kill the process. - 1.3.1 + 1.4.0 https://github.com/domsleee/forceops https://github.com/domsleee/forceops git @@ -10,7 +10,7 @@ lock file directory force delete https://github.com/domsleee/forceops/blob/main/CHANGELOG.md - net7.0 + net8.0 LatestMajor latest enable diff --git a/ForceOps.Lib/src/ForceOpsContext/ForceOpsContext.cs b/ForceOps.Lib/src/ForceOpsContext/ForceOpsContext.cs index 7ac2a2f..17d1142 100644 --- a/ForceOps.Lib/src/ForceOpsContext/ForceOpsContext.cs +++ b/ForceOps.Lib/src/ForceOpsContext/ForceOpsContext.cs @@ -6,12 +6,12 @@ public class ForceOpsContext /// The number of retries when performing an operation. /// For example, five retries equals six total attempts. /// - public int maxRetries = 5; + public int maxRetries = 10; /// /// The time to wait between before retrying the operation. /// - public TimeSpan retryDelay = TimeSpan.FromMilliseconds(500); + public TimeSpan retryDelay = TimeSpan.FromMilliseconds(50); public IProcessKiller processKiller; public IElevateUtils elevateUtils; diff --git a/ForceOps.Test/src/FileAndDirectoryDeleterTest.cs b/ForceOps.Test/src/FileAndDirectoryDeleterTest.cs index 6877ebe..8384764 100644 --- a/ForceOps.Test/src/FileAndDirectoryDeleterTest.cs +++ b/ForceOps.Test/src/FileAndDirectoryDeleterTest.cs @@ -21,12 +21,12 @@ public void DeletingDirectoryOpenInPowershellWorkingDirectory() Assert.IsType(exceptionWithNoRetries); Assert.StartsWith("The process cannot access the file", exceptionWithNoRetries.Message); - forceOpsContext.maxRetries = 5; + forceOpsContext.maxRetries = 10; var exceptionWithDirectoryStrategy = Record.Exception(() => fileAndDirectoryDeleter.DeleteDirectory(new DirectoryInfo(tempFolderPath))); Assert.True(null == exceptionWithDirectoryStrategy, testContext.fakeLoggerFactory.GetAllLogsString()); Assert.Matches(@"Exceeded retry count of 0. Failed. ForceOps process is not elevated. -Could not delete directory .*. Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); +Could not delete directory .*. Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); } [Fact] @@ -40,12 +40,12 @@ public void DeletingReadonlyDirectoryOpenInPowershellWorkingDirectory() Assert.IsType(exceptionWithNoRetries); Assert.StartsWith("The process cannot access the file", exceptionWithNoRetries.Message); - forceOpsContext.maxRetries = 5; + forceOpsContext.maxRetries = 10; var exceptionWithDirectoryStrategy = Record.Exception(() => fileAndDirectoryDeleter.DeleteDirectory(new DirectoryInfo(tempFolderPath))); Assert.True(null == exceptionWithDirectoryStrategy, testContext.fakeLoggerFactory.GetAllLogsString()); Assert.Matches(@"Exceeded retry count of 0. Failed. ForceOps process is not elevated. -Could not delete directory .*. Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); +Could not delete directory .*. Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); } [Fact] @@ -59,12 +59,12 @@ public void DeletingFileOpenByPowershell() Assert.IsType(exceptionWithNoRetries); Assert.StartsWith("The process cannot access the file", exceptionWithNoRetries.Message); - forceOpsContext.maxRetries = 5; + forceOpsContext.maxRetries = 10; var exceptionWithDirectoryStrategy = Record.Exception(() => fileAndDirectoryDeleter.DeleteFile(new FileInfo(tempFilePath))); Assert.True(null == exceptionWithDirectoryStrategy, testContext.fakeLoggerFactory.GetAllLogsString()); Assert.Matches($@"Exceeded retry count of 0. Failed. ForceOps process is not elevated. -Could not delete file .*. Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); +Could not delete file .*. Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); } [Fact] @@ -79,12 +79,12 @@ public void DeletingReadonlyFileOpenByPowershell() Assert.IsType(exceptionWithNoRetries); Assert.StartsWith("The process cannot access the file", exceptionWithNoRetries.Message); - forceOpsContext.maxRetries = 5; + forceOpsContext.maxRetries = 10; var exceptionWithDirectoryStrategy = Record.Exception(() => fileAndDirectoryDeleter.DeleteFile(new FileInfo(tempFilePath))); Assert.True(null == exceptionWithDirectoryStrategy, testContext.fakeLoggerFactory.GetAllLogsString()); Assert.Matches($@"Exceeded retry count of 0. Failed. ForceOps process is not elevated. -Could not delete file .*. Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); +Could not delete file .*. Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: \[\d+ \- powershell.exe\]", testContext.fakeLoggerFactory.GetAllLogsString()); } public ForceOpsMethodsTest() diff --git a/ForceOps/src/ForceOps.cs b/ForceOps/src/ForceOps.cs index 971ca86..ae6d7ec 100644 --- a/ForceOps/src/ForceOps.cs +++ b/ForceOps/src/ForceOps.cs @@ -63,8 +63,8 @@ Command CreateDeleteCommand() var forceOption = new Option(new[] { "-f", "--force" }, "Ignore nonexistent files and arguments."); var disableElevate = new Option(new[] { "-e", "--disable-elevate" }, "Do not attempt to elevate if the file can't be deleted."); - var retryDelay = new Option(new[] { "-d", "--retry-delay" }, () => 500, "Delay when retrying to delete a file, after deleting processes holding a lock."); - var maxRetries = new Option(new[] { "-n", "--max-retries" }, () => 5, "Number of retries when deleting a locked file."); + var retryDelay = new Option(new[] { "-d", "--retry-delay" }, () => 50, "Delay when retrying to delete a file, after deleting processes holding a lock."); + var maxRetries = new Option(new[] { "-n", "--max-retries" }, () => 10, "Number of retries when deleting a locked file."); var deleteCommand = new Command("delete", "Delete files or a directories recursively.") { diff --git a/README.md b/README.md index 5fefe88..0989b53 100644 --- a/README.md +++ b/README.md @@ -21,23 +21,33 @@ Refer also to `10.4 Example: file deletion in Windows` from "A Philosophy of Sof ### Deleting when a process owned by the current user is using it ```shell ❯ forceops rm .\bin\ -[14:55:33 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.dll". Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [100724 - myprogram.exe]. -[14:55:34 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.dll". Beginning retry 2/5 in 500ms. ForceOps process is not elevated. Found 0 processes to try to kill: []. +[14:55:33 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.dll". Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [100724 - myprogram.exe]. +[14:55:34 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.dll". Beginning retry 2/10 in 50ms. ForceOps process is not elevated. Found 0 processes to try to kill: []. ``` ### Deleting when a process owned by another user is using it (e.g. a windows service) ```shell ❯ forceops rm .\bin\Debug\net6\myprogram.exe -[15:07:34 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 1/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. -[15:07:34 WRN] Failed to kill process 115744: Access is denied. -[15:07:35 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 2/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. -[15:07:35 WRN] Failed to kill process 115744: Access is denied. -[15:07:36 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 3/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. -[15:07:37 WRN] Failed to kill process 115744: Access is denied. -[15:07:37 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 4/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. -[15:07:38 WRN] Failed to kill process 115744: Access is denied. -[15:07:38 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 5/5 in 500ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 1/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. [15:07:39 WRN] Failed to kill process 115744: Access is denied. -[15:07:39 INF] Exceeded retry count of 5. Failed. ForceOps process is not elevated. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 2/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 3/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 4/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 5/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 6/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 7/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 8/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 9/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Could not delete file "C:\Users\user\myprogram\bin\Debug\net6\myprogram.exe". Beginning retry 10/10 in 50ms. ForceOps process is not elevated. Found 1 process to try to kill: [115744 - ]. +[15:07:39 WRN] Failed to kill process 115744: Access is denied. +[15:07:39 INF] Exceeded retry count of 10. Failed. ForceOps process is not elevated. [15:07:39 INF] Unable to perform operation as an unelevated process. Retrying as elevated and logging to "C:\Users\user\AppData\Local\Temp\tmp9C14.tmp". [15:07:42 INF] Successfully deleted as admin ```