Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
dotnet-version: '9.0.x'
- name: Run benchmark
run: cd ForceOps.Benchmarks && dotnet run -c release --exporters json --filter '*'
- name: Store benchmark result
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install Dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
dotnet-version: "9.0.x"

- name: Dotnet Installation Info
run: dotnet --info
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Install Dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
dotnet-version: "9.0.x"

- name: Directory structure
run: |
Expand Down Expand Up @@ -61,7 +61,7 @@ jobs:
with:
draft: true
name: "${{ steps.get_version.outputs.version }}"
files: ForceOps/bin_aot/Release/net8.0/win-x64/publish/ForceOps.exe
files: ForceOps/bin_aot/Release/net9.0/win-x64/publish/ForceOps.exe
tag_name: "${{ steps.get_version.outputs.version }}"

- name: Publish NuGet
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PackageReleaseNotes>https://github.com/domsleee/forceops/blob/main/CHANGELOG.md</PackageReleaseNotes>
<IsPackable>false</IsPackable>

<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<RollForward>LatestMajor</RollForward>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
2 changes: 1 addition & 1 deletion ForceOps.Benchmarks/ForceOps.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions ForceOps.Benchmarks/src/FileAndDirectoryDeleterBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using ForceOps.Lib;

namespace ForceOps.Benchmarks;

// [SimpleJob(RuntimeMoniker.NativeAot80)]
[SimpleJob(RuntimeMoniker.Net80)]
[SimpleJob]
public class FileAndDirectoryDeleterBenchmark
{
readonly List<byte[]> fileDatas = new();
Expand Down
4 changes: 2 additions & 2 deletions ForceOps.Lib/ForceOps.Lib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="LockChecker" Version="0.9.33-gf4fccad662" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
</ItemGroup>
</Project>
9 changes: 4 additions & 5 deletions ForceOps.Test/ForceOps.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
<PackageReference Include="System.Reactive" Version="6.0.0" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<PackageReference Include="System.Reactive" Version="6.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
57 changes: 28 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ Only supports windows, and not planned to support linux.

Uses [LockChecker](https://github.com/domsleee/LockCheck) to find processes locking files, and will elevate itself if it the process is owned by another user.

See [Benchmarks](https://domsleee.github.io/ForceOps/) on github pages.
## Installation

Refer also to `10.4 Example: file deletion in Windows` from "A Philosophy of Software Design", which explains why this is a windows specific problem. Linux does not prevent the user from deleting a file if it is being used, see [unlink](https://man7.org/linux/man-pages/man2/unlink.2.html#:~:text=unlink()%20deletes%20a%20name,is%20made%20available%20for%20reuse.):
```shell
dotnet tool install -g forceops
```

> If the name was the last link to a file but any processes still
have the file open, the file will remain in existence until the
last file descriptor referring to it is closed.
To update:
```
dotnet tool update -g forceops
```

Alternatively, the executable is available for download in [the latest release]([releases](https://github.com/domsleee/ForceOps/releases/atest)).

## Examples

## Usage: As a CLI
### Deleting when a process owned by the current user is using it
```shell
❯ forceops rm .\bin\
Expand Down Expand Up @@ -52,29 +58,6 @@ Refer also to `10.4 Example: file deletion in Windows` from "A Philosophy of Sof
[15:07:42 INF] Successfully deleted as admin
```


## Supported operations

Currently, only `delete` is supported.

Operations like `move` and `copy` can have similar issues if they are overriding files or the source file is in use. It would be reasonable to support these operations in a similar way.

For copying, consider using [Microsoft.Build.CopyOnWrite](https://github.com/microsoft/MSBuildSdks/tree/main/src/CopyOnWrite).

## Usage: As a CLI

To install the CLI, use the latest exe from [releases](https://github.com/domsleee/ForceOps/releases).

Alternatively, it can be installed as a tool, using the [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).
```bash
dotnet tool install -g forceops
```

To delete a file:
```bash
forceops delete file.txt
```

## Usage: As a library

See the [ForceOps.Lib](https://www.nuget.org/packages/ForceOps.Lib) package.
Expand All @@ -96,3 +79,19 @@ RelaunchHelpers.RunWithRelaunchAsElevated(() =>
}
}, () => args.ToList(), forceOpsContext);
```

## Context

See [Benchmarks](https://domsleee.github.io/ForceOps/) on github pages.

Refer also to `10.4 Example: file deletion in Windows` from "A Philosophy of Software Design", which explains why this is a windows specific problem. Linux does not prevent the user from deleting a file if it is being used, see [unlink](https://man7.org/linux/man-pages/man2/unlink.2.html#:~:text=unlink()%20deletes%20a%20name,is%20made%20available%20for%20reuse.):

> If the name was the last link to a file but any processes still
have the file open, the file will remain in existence until the
last file descriptor referring to it is closed.

Currently, only `delete` is supported.

Operations like `move` and `copy` can have similar issues if they are overriding files or the source file is in use. It would be reasonable to support these operations in a similar way.

For copying, consider using [Microsoft.Build.CopyOnWrite](https://github.com/microsoft/MSBuildSdks/tree/main/src/CopyOnWrite).
6 changes: 6 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"sdk": {
"version": "9.0.200",
"rollForward": "latestFeature"
}
}
Loading