├── imgs ├── 222.gif ├── 333.gif └── 11111.gif ├── src ├── DeletionTool │ ├── obj │ │ ├── Debug │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ │ ├── DeletionTool.csproj.CoreCompileInputs.cache │ │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ └── DeletionTool.csproj.FileListAbsolute.txt │ │ └── Release │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ │ ├── DeletionTool.csproj.CoreCompileInputs.cache │ │ │ ├── DeletionTool.exe │ │ │ ├── DeletionTool.pdb │ │ │ ├── DeletionTool.FormMain.resources │ │ │ ├── DeletionTool.FormFixPath.resources │ │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ │ ├── DeletionTool.Properties.Resources.resources │ │ │ ├── DeletionTool.csproj.GenerateResource.Cache │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── DeletionTool.csprojResolveAssemblyReference.cache │ │ │ └── DeletionTool.csproj.FileListAbsolute.txt │ ├── icon.ico │ ├── bin │ │ └── Release │ │ │ └── DeletionTool.zip │ ├── App.config │ ├── Properties │ │ ├── Settings.settings │ │ ├── AssemblyInfo.cs │ │ ├── Settings.Designer.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── AdvancedDeletion │ │ ├── Utilities │ │ │ ├── Win32API │ │ │ │ ├── RmHelper │ │ │ │ │ ├── DefaultRmHelper.cs │ │ │ │ │ └── RmHelper.cs │ │ │ │ ├── UnmanagedHandles │ │ │ │ │ ├── NativeNormalHandle.cs │ │ │ │ │ ├── NativeFindFileHandle.cs │ │ │ │ │ └── AllocatedMemoryHandle.cs │ │ │ │ ├── NativeAPI.cs │ │ │ │ └── NativeTypes.cs │ │ │ ├── StringListPool.cs │ │ │ └── Unlocker.cs │ │ └── AdvancedDeletion.cs │ ├── FormFixPath.cs │ ├── Program.cs │ ├── FormFixPath.Designer.cs │ ├── DeletionTool.csproj │ ├── NumberBox.cs │ ├── FormFixPath.resx │ ├── FormMain.Designer.cs │ ├── FormMain.cs │ └── FormMain.resx ├── .vs │ └── DeletionTool │ │ └── v15 │ │ ├── .suo │ │ └── sqlite3 │ │ └── storage.ide └── DeletionTool.sln ├── LICENSE └── README.md /imgs/222.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/imgs/222.gif -------------------------------------------------------------------------------- /imgs/333.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/imgs/333.gif -------------------------------------------------------------------------------- /imgs/11111.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/imgs/11111.gif -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/DeletionTool/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/icon.ico -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/DeletionTool.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | f79670f7d85e10e766432313096e63eeb831f745 2 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | f79670f7d85e10e766432313096e63eeb831f745 2 | -------------------------------------------------------------------------------- /src/.vs/DeletionTool/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/.vs/DeletionTool/v15/.suo -------------------------------------------------------------------------------- /src/.vs/DeletionTool/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/.vs/DeletionTool/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /src/DeletionTool/bin/Release/DeletionTool.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/bin/Release/DeletionTool.zip -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.exe -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.pdb -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.FormMain.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.FormMain.resources -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.FormFixPath.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.FormFixPath.resources -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.Properties.Resources.resources -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/differentrain/DeletionTool/HEAD/src/DeletionTool/obj/Release/DeletionTool.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /src/DeletionTool/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/DeletionTool/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/RmHelper/DefaultRmHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace YYProject.AdvancedDeletion 8 | { 9 | internal sealed class DefaultRmHelper : RmHelper 10 | { 11 | 12 | public override Boolean TryGetHolderListOfFiles(String[] fileNames, out RmProcessInfo[] result) 13 | { 14 | 15 | result = null; 16 | if (NativeAPI.TryRmRegisterResources(base._SessionHandle, fileNames, null, null) && NativeAPI.TryRmGetList(base._SessionHandle, out var suggestion, out result)) 17 | { 18 | return true; 19 | } 20 | return false; 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/StringListPool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace YYProject.AdvancedDeletion 9 | { 10 | internal static class StringListPool 11 | { 12 | private static ConcurrentBag> _Objects = new ConcurrentBag>(); 13 | 14 | public static List Rent() 15 | { 16 | if (_Objects.TryTake(out var item)) 17 | { 18 | return item; 19 | } 20 | return new List(); 21 | } 22 | 23 | public static void Return(List ls) 24 | { 25 | ls.Clear(); 26 | _Objects.Add(ls); 27 | } 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/UnmanagedHandles/NativeNormalHandle.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Permissions; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | /// 12 | /// Provides a handle type to manage the normal unsafe handle. 13 | /// 14 | [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] 15 | internal sealed class NativeNormalHandle : SafeHandleZeroOrMinusOneIsInvalid 16 | { 17 | private NativeNormalHandle() : base(true) { } 18 | 19 | protected override Boolean ReleaseHandle() 20 | { 21 | var q = NativeAPI.TryCloseHandle(this.handle); 22 | return q; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/UnmanagedHandles/NativeFindFileHandle.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Permissions; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | /// 12 | /// Provides a handle type to manage the find-file-handle, which was openned by FindFirstFile API. 13 | /// 14 | [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] 15 | internal sealed class NativeFindFileHandle : SafeHandleZeroOrMinusOneIsInvalid 16 | { 17 | private NativeFindFileHandle() : base(true) { } 18 | 19 | protected override Boolean ReleaseHandle() 20 | { 21 | return NativeAPI.TryCloseFindHandle(this.handle); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Debug/DeletionTool.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Debug\DeletionTool.exe.config 2 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Debug\DeletionTool.exe 3 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Debug\DeletionTool.pdb 4 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.FormFixPath.resources 5 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.FormMain.resources 6 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.Properties.Resources.resources 7 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.csproj.GenerateResource.Cache 8 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.csproj.CoreCompileInputs.cache 9 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.exe 10 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Debug\DeletionTool.pdb 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 differentrain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/DeletionTool/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("DeletionTool")] 9 | [assembly: AssemblyDescription("DeletionTool")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("differentrain")] 12 | [assembly: AssemblyProduct("DeletionTool")] 13 | [assembly: AssemblyCopyright("differentrain")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("fca38a90-bd4b-4958-b90c-9fa89e2b78ca")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/DeletionTool/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DeletionTool.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/DeletionTool/FormFixPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace DeletionTool 12 | { 13 | public partial class FormFixPath : Form 14 | { 15 | private String _Dots; 16 | 17 | public String Dots => _Dots; 18 | 19 | public FormFixPath() 20 | { 21 | InitializeComponent(); 22 | LabelDot.Text = FormMain.DotCount; 23 | LabelMsg.Text = FormMain.ErrorPathMsg; 24 | ButtonOK.Text = FormMain.ButtonOKText; 25 | ButtonCancle.Text = FormMain.ButtonCancleText; 26 | this.Text = FormMain.FormFixPathText; 27 | NumberBoxDot.Text = "2"; 28 | } 29 | 30 | private void ButtonOK_Click(object sender, EventArgs e) 31 | { 32 | _Dots = new String('.', NumberBoxDot.Value); 33 | this.DialogResult = DialogResult.OK; 34 | this.Close(); 35 | } 36 | 37 | private void ButtonCancle_Click(object sender, EventArgs e) 38 | { 39 | this.DialogResult = DialogResult.Cancel; 40 | this.Close(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeletionTool 2 | A gadget for file/directory deletion in Windows. 3 | 4 | **This repo is archived, use [Delapp](https://github.com/differentrain/Delapp) insteaded.** 5 | 6 | **此仓库已存档,使用 [Delapp](https://github.com/differentrain/Delapp) 进行代替。** 7 | 8 | 9 | Windows下的删除文件/文件夹的小工具。 10 | 11 | [Download](https://github.com/differentrain/DeletionTool/raw/master/src/DeletionTool/bin/Release/DeletionTool.zip) 12 | 13 | ## Updates 更新 14 | 15 | `2017.09.12` New Functionality: drag&drop files or(and) directories on exe, program shoud delete object without GUI, instead of the system sound of "EmptyRecycleBin". 16 | 17 | `2017.09.12` 新增功能: 拖拽文件或(和)文件夹到exe上面,程序会在不使用GUI的情况下将其删除, 并播放系统声音"EmptyRecycleBin". 18 | 19 | ## Notice 须知 20 | 21 | `DeletionTool` can delete the file/directory that is currently in use or end with special characters, such as `..`, But make it clear that you know what you are doing when using it. 22 | 23 | `DeletionTool` 可以删除以特殊的字符结尾(如`..`)或正在使用的文件/文件夹, 但使用时应清楚地认识到到自己是在做什么。 24 | 25 | ## Demonstrate 演示 26 |   27 | ![image](https://github.com/differentrain/DeletionTool/raw/master/imgs/333.gif) 28 |   29 | *** 30 | 31 | ![image](https://github.com/differentrain/DeletionTool/raw/master/imgs/11111.gif) 32 |   33 | *** 34 | 35 | ![image](https://github.com/differentrain/DeletionTool/raw/master/imgs/222.gif) 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/DeletionTool.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeletionTool", "DeletionTool\DeletionTool.csproj", "{FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x86 = Debug|x86 12 | Release|Any CPU = Release|Any CPU 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Debug|x86.ActiveCfg = Debug|Any CPU 19 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Debug|x86.Build.0 = Debug|Any CPU 20 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Release|x86.ActiveCfg = Release|Any CPU 23 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA}.Release|x86.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {D93D72E3-F739-499F-812F-1BDA2E87467A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/UnmanagedHandles/AllocatedMemoryHandle.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | /// 12 | /// Provides a handle type to manage the unmanaged memory pointer. 13 | /// 14 | internal sealed class AllocatedMemoryHandle : SafeHandleZeroOrMinusOneIsInvalid 15 | { 16 | private Int32 _Size; 17 | 18 | /// 19 | /// The memory size that has been allocated. 20 | /// 21 | public Int32 Size => _Size; 22 | /// 23 | /// Constructor. 24 | /// 25 | /// The memory size to be allocated. 26 | public AllocatedMemoryHandle(Int32 size) : base(true) 27 | { 28 | _Size = size; 29 | this.handle = Marshal.AllocHGlobal(size); 30 | } 31 | /// 32 | /// Change the memory size. 33 | /// 34 | /// The new memory size. 35 | public void ChangeMemorySize(Int32 newSize) 36 | { 37 | if (!this.IsClosed) 38 | { 39 | Marshal.FreeHGlobal(this.handle); 40 | } 41 | this.handle = Marshal.AllocHGlobal(newSize); 42 | _Size = newSize; 43 | } 44 | 45 | protected override Boolean ReleaseHandle() 46 | { 47 | try 48 | { 49 | Marshal.FreeHGlobal(this.handle); 50 | return true; 51 | } 52 | catch 53 | { 54 | return false; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/DeletionTool/obj/Release/DeletionTool.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Release\DeletionTool.exe.config 2 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Release\DeletionTool.exe 3 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\bin\Release\DeletionTool.pdb 4 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.FormFixPath.resources 5 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.FormMain.resources 6 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.Properties.Resources.resources 7 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.csproj.GenerateResource.Cache 8 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.csproj.CoreCompileInputs.cache 9 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.exe 10 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.pdb 11 | Z:\data\Works\LocalGit\DeletionTool\DeletionTool\obj\Release\DeletionTool.csprojResolveAssemblyReference.cache 12 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\bin\Release\DeletionTool.exe.config 13 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\bin\Release\DeletionTool.exe 14 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\bin\Release\DeletionTool.pdb 15 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.csprojResolveAssemblyReference.cache 16 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.FormFixPath.resources 17 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.FormMain.resources 18 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.Properties.Resources.resources 19 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.csproj.GenerateResource.Cache 20 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.csproj.CoreCompileInputs.cache 21 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.exe 22 | Z:\data\Works\LocalGit\DeletionTool\src\DeletionTool\obj\Release\DeletionTool.pdb 23 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/RmHelper/RmHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace YYProject.AdvancedDeletion 8 | { 9 | /// 10 | /// Restart Manager helper. 11 | /// See https://msdn.microsoft.com/en-us/library/windows/desktop/cc948910. 12 | /// 13 | internal abstract class RmHelper 14 | { 15 | private static RmHelper _Shared = new DefaultRmHelper(); 16 | private Boolean _IsClosed = true; 17 | protected UInt32 _SessionHandle; 18 | protected String _SessionKey; 19 | 20 | 21 | /// 22 | /// Gets a shared instance of . 23 | /// 24 | public static RmHelper SharedInstance => _Shared; 25 | 26 | /// 27 | /// Gets whether the session is finished. 28 | /// 29 | public Boolean IsClosed => _IsClosed; 30 | 31 | /// 32 | /// Start the session. 33 | /// 34 | public void StartSession() 35 | { 36 | if (_IsClosed == true) 37 | { 38 | NativeAPI.TryRmStartSession(out _SessionHandle, out _SessionKey); 39 | _IsClosed = false; 40 | } 41 | 42 | } 43 | /// 44 | /// Close the session. 45 | /// 46 | public void EndSession() 47 | { 48 | if (_IsClosed == false) 49 | { 50 | NativeAPI.TryRmEndSession(_SessionHandle); 51 | _IsClosed = true; 52 | } 53 | 54 | } 55 | ~RmHelper() 56 | { 57 | EndSession(); 58 | } 59 | 60 | /// 61 | /// Gets a [] contains all process that are using object files. 62 | /// 63 | /// An file path list. 64 | /// Result. 65 | public abstract Boolean TryGetHolderListOfFiles(String[] fileNames, out RmProcessInfo[] result); 66 | 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/DeletionTool/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Media; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | using YYProject.AdvancedDeletion; 7 | 8 | namespace DeletionTool 9 | { 10 | static class Program 11 | { 12 | #region Doubts 13 | /*[DllImport("winmm.dll", EntryPoint = "sndPlaySound")] 14 | [return: MarshalAs(UnmanagedType.Bool)] 15 | private static extern Boolean SndPlaySound(String pszSound, Int32 fuSound); 16 | private const Int32 SND_SYSTEM = 0x00200000; 17 | 18 | SndPlaySound("EmptyRecycleBin", SND_SYSTEM ); //The sound that was played is wrong, but I don't know why…… 19 | */ 20 | #endregion 21 | 22 | 23 | 24 | /// 25 | /// 应用程序的主入口点。 26 | /// 27 | [STAThread] 28 | static void Main(String[] args) 29 | { 30 | using (System.Threading.Mutex mutex = new System.Threading.Mutex(true, "790586ef-8565-4f70-9aa6-639b9c6c25db", out var createNew)) 31 | { 32 | if (createNew) 33 | { 34 | if (args.Length > 0) 35 | { 36 | var hasDeleted = false; 37 | Parallel.ForEach(args, item => { 38 | if (AdvancedDeletion.IsExists(item, out var hasDot)) 39 | { 40 | hasDeleted = true; 41 | AdvancedDeletion.Delete(item); 42 | } 43 | }); 44 | if (hasDeleted) 45 | { 46 | using (var sound = new SoundPlayer(Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\EmptyRecycleBin\.Current", false).GetValue(null) as String)) 47 | { 48 | sound.PlaySync(); 49 | } 50 | } 51 | return; 52 | } 53 | Application.EnableVisualStyles(); 54 | Application.SetCompatibleTextRenderingDefault(false); 55 | Application.Run(new FormMain()); 56 | } 57 | else 58 | { 59 | Environment.Exit(1);//It's not required but can send system a non-normal exit signal…… 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/DeletionTool/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本: 4.0.30319.42000 5 | // 6 | // 对此文件的更改可能导致不正确的行为,如果 7 | // 重新生成代码,则所做更改将丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DeletionTool.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 强类型资源类,用于查找本地化字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 返回此类使用的缓存 ResourceManager 实例。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DeletionTool.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 覆盖当前线程的 CurrentUICulture 属性 56 | /// 使用此强类型的资源类的资源查找。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/DeletionTool/FormFixPath.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DeletionTool 2 | { 3 | partial class FormFixPath 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.LabelMsg = new System.Windows.Forms.Label(); 32 | this.ButtonOK = new System.Windows.Forms.Button(); 33 | this.ButtonCancle = new System.Windows.Forms.Button(); 34 | this.LabelDot = new System.Windows.Forms.Label(); 35 | this.NumberBoxDot = new DeletionTool.NumberBox(); 36 | this.SuspendLayout(); 37 | // 38 | // LabelMsg 39 | // 40 | this.LabelMsg.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; 41 | this.LabelMsg.Location = new System.Drawing.Point(3, 9); 42 | this.LabelMsg.Name = "LabelMsg"; 43 | this.LabelMsg.Size = new System.Drawing.Size(280, 27); 44 | this.LabelMsg.TabIndex = 0; 45 | // 46 | // ButtonOK 47 | // 48 | this.ButtonOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 49 | this.ButtonOK.Location = new System.Drawing.Point(147, 39); 50 | this.ButtonOK.Name = "ButtonOK"; 51 | this.ButtonOK.Size = new System.Drawing.Size(53, 24); 52 | this.ButtonOK.TabIndex = 0; 53 | this.ButtonOK.TabStop = false; 54 | this.ButtonOK.UseVisualStyleBackColor = true; 55 | this.ButtonOK.Click += new System.EventHandler(this.ButtonOK_Click); 56 | // 57 | // ButtonCancle 58 | // 59 | this.ButtonCancle.DialogResult = System.Windows.Forms.DialogResult.Cancel; 60 | this.ButtonCancle.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 61 | this.ButtonCancle.Location = new System.Drawing.Point(221, 39); 62 | this.ButtonCancle.Name = "ButtonCancle"; 63 | this.ButtonCancle.Size = new System.Drawing.Size(53, 24); 64 | this.ButtonCancle.TabIndex = 0; 65 | this.ButtonCancle.TabStop = false; 66 | this.ButtonCancle.UseVisualStyleBackColor = true; 67 | this.ButtonCancle.Click += new System.EventHandler(this.ButtonCancle_Click); 68 | // 69 | // LabelDot 70 | // 71 | this.LabelDot.Location = new System.Drawing.Point(9, 44); 72 | this.LabelDot.Name = "LabelDot"; 73 | this.LabelDot.Size = new System.Drawing.Size(82, 19); 74 | this.LabelDot.TabIndex = 4; 75 | // 76 | // NumberBoxDot 77 | // 78 | this.NumberBoxDot.Location = new System.Drawing.Point(97, 40); 79 | this.NumberBoxDot.MaxNum = 99; 80 | this.NumberBoxDot.MinNum = 2; 81 | this.NumberBoxDot.Name = "NumberBoxDot"; 82 | this.NumberBoxDot.Size = new System.Drawing.Size(33, 21); 83 | this.NumberBoxDot.TabIndex = 5; 84 | // 85 | // FormFixPath 86 | // 87 | this.AcceptButton = this.ButtonOK; 88 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 89 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 90 | this.CancelButton = this.ButtonCancle; 91 | this.ClientSize = new System.Drawing.Size(286, 69); 92 | this.ControlBox = false; 93 | this.Controls.Add(this.NumberBoxDot); 94 | this.Controls.Add(this.LabelDot); 95 | this.Controls.Add(this.ButtonCancle); 96 | this.Controls.Add(this.ButtonOK); 97 | this.Controls.Add(this.LabelMsg); 98 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 99 | this.Name = "FormFixPath"; 100 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 101 | this.Text = "FormFixPath"; 102 | this.ResumeLayout(false); 103 | this.PerformLayout(); 104 | 105 | } 106 | 107 | #endregion 108 | 109 | private System.Windows.Forms.Label LabelMsg; 110 | private System.Windows.Forms.Button ButtonOK; 111 | private System.Windows.Forms.Button ButtonCancle; 112 | private System.Windows.Forms.Label LabelDot; 113 | private NumberBox NumberBoxDot; 114 | } 115 | } -------------------------------------------------------------------------------- /src/DeletionTool/DeletionTool.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FCA38A90-BD4B-4958-B90C-9FA89E2B78CA} 8 | WinExe 9 | DeletionTool 10 | DeletionTool 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | icon.ico 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Form 62 | 63 | 64 | FormFixPath.cs 65 | 66 | 67 | Form 68 | 69 | 70 | FormMain.cs 71 | 72 | 73 | 74 | 75 | 76 | Component 77 | 78 | 79 | 80 | 81 | 82 | FormFixPath.cs 83 | 84 | 85 | FormMain.cs 86 | 87 | 88 | ResXFileCodeGenerator 89 | Resources.Designer.cs 90 | Designer 91 | 92 | 93 | True 94 | Resources.resx 95 | 96 | 97 | SettingsSingleFileGenerator 98 | Settings.Designer.cs 99 | 100 | 101 | True 102 | Settings.settings 103 | True 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/DeletionTool/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /src/DeletionTool/NumberBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace DeletionTool 9 | { 10 | public class NumberBox : TextBox 11 | { 12 | 13 | private Int32 _MinNum; 14 | private Int32 _MaxNum; 15 | 16 | 17 | 18 | public Int32 MinNum 19 | { 20 | get { return _MinNum; } 21 | set { _MinNum = value; } 22 | } 23 | 24 | public Int32 MaxNum 25 | { 26 | get { return _MaxNum; } 27 | set { _MaxNum = value; } 28 | } 29 | 30 | public Int32 Value => Int32.Parse(this.Text); 31 | 32 | private Boolean IsNop(string Str) 33 | { 34 | 35 | if (Str.Length == 0) 36 | return false; 37 | 38 | if (Str[0] == '0' && Str.Length > 1) 39 | return true; 40 | 41 | if (Str.Contains("-")) 42 | { 43 | if (_MinNum < 0) 44 | { 45 | if (Str.IndexOf("-") != Str.LastIndexOf("-") || Str.IndexOf("-") != 0) 46 | return true; 47 | } 48 | else 49 | { 50 | return true; 51 | } 52 | } 53 | 54 | try 55 | { 56 | if (Convert.ToInt64(Str) > _MaxNum || Convert.ToInt64(Str) < _MinNum) 57 | return true; 58 | } 59 | catch (Exception) 60 | { 61 | return true; 62 | } 63 | 64 | return false; 65 | } 66 | 67 | 68 | protected override void OnKeyPress(KeyPressEventArgs e) 69 | { 70 | switch (Convert.ToInt32(e.KeyChar)) 71 | { 72 | 73 | case 8: 74 | //Keys.Back 75 | if (this.SelectionLength == 0) 76 | { 77 | if (this.SelectionStart > 0) 78 | e.Handled = IsNop(this.Text.Remove(this.SelectionStart - 1, 1)); 79 | } 80 | else 81 | { 82 | e.Handled = IsNop(this.Text.Remove(this.SelectionStart, this.SelectionLength)); 83 | } 84 | break; 85 | case 22: 86 | //V 87 | try 88 | { 89 | e.Handled = IsNop(this.Text.Remove(this.SelectionStart, this.SelectionLength).Insert(this.SelectionStart, Convert.ToInt64(Clipboard.GetText()).ToString())); 90 | } 91 | catch (Exception) 92 | { 93 | e.Handled = true; 94 | } 95 | break; 96 | case 24: 97 | //X 98 | e.Handled = IsNop(this.Text.Remove(this.SelectionStart, this.SelectionLength)); 99 | break; 100 | case 3: 101 | e.Handled = false; 102 | break; 103 | default: 104 | e.Handled = IsNop(this.Text.Remove(this.SelectionStart, this.SelectionLength).Insert(this.SelectionStart, e.KeyChar.ToString())); 105 | break; 106 | } 107 | 108 | base.OnKeyPress(e); 109 | } 110 | 111 | protected override void OnKeyDown(KeyEventArgs e) 112 | { 113 | switch (e.KeyCode) 114 | { 115 | case Keys.Back: 116 | case Keys.OemMinus: 117 | case Keys.Subtract: 118 | case Keys.D0: 119 | case Keys.D1: 120 | case Keys.D2: 121 | case Keys.D3: 122 | case Keys.D4: 123 | case Keys.D5: 124 | case Keys.D6: 125 | case Keys.D7: 126 | case Keys.D8: 127 | case Keys.D9: 128 | case Keys.NumPad0: 129 | case Keys.NumPad1: 130 | case Keys.NumPad2: 131 | case Keys.NumPad3: 132 | case Keys.NumPad4: 133 | case Keys.NumPad5: 134 | case Keys.NumPad6: 135 | case Keys.NumPad7: 136 | case Keys.NumPad8: 137 | case Keys.NumPad9: 138 | case Keys.Tab: 139 | case Keys.Left: 140 | case Keys.Right: 141 | if (e.Control == true || e.Shift == true) 142 | e.SuppressKeyPress = true; 143 | break; 144 | case Keys.C: 145 | case Keys.A: 146 | case Keys.V: 147 | case Keys.X: 148 | if (e.Control == false || e.Shift == true) 149 | e.SuppressKeyPress = true; 150 | break; 151 | case Keys.Delete: 152 | if (this.SelectionLength == 0) 153 | { 154 | e.SuppressKeyPress = IsNop(this.Text.Remove(this.SelectionStart, 1)); 155 | } 156 | else 157 | { 158 | e.SuppressKeyPress = IsNop(this.Text.Remove(this.SelectionStart, this.SelectionLength)); 159 | } 160 | if (e.Control == true || e.Shift == true) 161 | e.SuppressKeyPress = true; 162 | 163 | break; 164 | default: 165 | e.SuppressKeyPress = true; 166 | break; 167 | } 168 | base.OnKeyDown(e); 169 | } 170 | 171 | protected override void OnTextChanged(EventArgs e) 172 | { 173 | if (String.IsNullOrEmpty(this.Text)) this.Text = this.MinNum.ToString(); 174 | base.OnTextChanged(e); 175 | 176 | } 177 | 178 | 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/DeletionTool/FormFixPath.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /src/DeletionTool/FormMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DeletionTool 2 | { 3 | partial class FormMain 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain)); 32 | this.ButtonOK = new System.Windows.Forms.Button(); 33 | this.CheckBoxDelete = new System.Windows.Forms.CheckBox(); 34 | this.LabelTips = new System.Windows.Forms.Label(); 35 | this.LabelPath = new System.Windows.Forms.Label(); 36 | this.BackgroundWorkerDel = new System.ComponentModel.BackgroundWorker(); 37 | this.SuspendLayout(); 38 | // 39 | // ButtonOK 40 | // 41 | this.ButtonOK.BackColor = System.Drawing.SystemColors.WindowFrame; 42 | this.ButtonOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 43 | this.ButtonOK.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 44 | this.ButtonOK.ForeColor = System.Drawing.SystemColors.GradientActiveCaption; 45 | this.ButtonOK.Location = new System.Drawing.Point(228, 37); 46 | this.ButtonOK.Name = "ButtonOK"; 47 | this.ButtonOK.Size = new System.Drawing.Size(50, 24); 48 | this.ButtonOK.TabIndex = 0; 49 | this.ButtonOK.TabStop = false; 50 | this.ButtonOK.UseVisualStyleBackColor = false; 51 | this.ButtonOK.Click += new System.EventHandler(this.ButtonOK_Click); 52 | // 53 | // CheckBoxDelete 54 | // 55 | this.CheckBoxDelete.AutoSize = true; 56 | this.CheckBoxDelete.BackColor = System.Drawing.SystemColors.WindowFrame; 57 | this.CheckBoxDelete.ForeColor = System.Drawing.SystemColors.GradientActiveCaption; 58 | this.CheckBoxDelete.Location = new System.Drawing.Point(168, 42); 59 | this.CheckBoxDelete.Name = "CheckBoxDelete"; 60 | this.CheckBoxDelete.Size = new System.Drawing.Size(15, 14); 61 | this.CheckBoxDelete.TabIndex = 0; 62 | this.CheckBoxDelete.TabStop = false; 63 | this.CheckBoxDelete.UseVisualStyleBackColor = false; 64 | this.CheckBoxDelete.CheckedChanged += new System.EventHandler(this.CheckBoxDelete_CheckedChanged); 65 | // 66 | // LabelTips 67 | // 68 | this.LabelTips.ForeColor = System.Drawing.SystemColors.Info; 69 | this.LabelTips.Location = new System.Drawing.Point(12, 41); 70 | this.LabelTips.Name = "LabelTips"; 71 | this.LabelTips.Size = new System.Drawing.Size(113, 17); 72 | this.LabelTips.TabIndex = 4; 73 | this.LabelTips.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 74 | // 75 | // LabelPath 76 | // 77 | this.LabelPath.AllowDrop = true; 78 | this.LabelPath.BackColor = System.Drawing.SystemColors.GradientActiveCaption; 79 | this.LabelPath.Location = new System.Drawing.Point(6, 9); 80 | this.LabelPath.Name = "LabelPath"; 81 | this.LabelPath.Size = new System.Drawing.Size(270, 16); 82 | this.LabelPath.TabIndex = 5; 83 | this.LabelPath.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 84 | this.LabelPath.DragDrop += new System.Windows.Forms.DragEventHandler(this.LabelPath_DragDrop); 85 | this.LabelPath.DragEnter += new System.Windows.Forms.DragEventHandler(this.LabelPath_DragEnter); 86 | // 87 | // BackgroundWorkerDel 88 | // 89 | this.BackgroundWorkerDel.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorkerDel_DoWork); 90 | this.BackgroundWorkerDel.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorkerDel_RunWorkerCompleted); 91 | // 92 | // FormMain 93 | // 94 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 95 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 96 | this.BackColor = System.Drawing.SystemColors.WindowFrame; 97 | this.ClientSize = new System.Drawing.Size(283, 68); 98 | this.Controls.Add(this.LabelPath); 99 | this.Controls.Add(this.LabelTips); 100 | this.Controls.Add(this.CheckBoxDelete); 101 | this.Controls.Add(this.ButtonOK); 102 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 103 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 104 | this.MaximizeBox = false; 105 | this.Name = "FormMain"; 106 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 107 | this.Text = "DeletionTool"; 108 | this.ResumeLayout(false); 109 | this.PerformLayout(); 110 | 111 | } 112 | 113 | #endregion 114 | 115 | private System.Windows.Forms.Button ButtonOK; 116 | private System.Windows.Forms.CheckBox CheckBoxDelete; 117 | private System.Windows.Forms.Label LabelTips; 118 | private System.Windows.Forms.Label LabelPath; 119 | private System.ComponentModel.BackgroundWorker BackgroundWorkerDel; 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /src/DeletionTool/FormMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | using YYProject.AdvancedDeletion; 13 | 14 | namespace DeletionTool 15 | { 16 | 17 | 18 | public partial class FormMain : Form 19 | { 20 | 21 | private FormFixPath FPForm = new FormFixPath(); 22 | 23 | #region Initialize 24 | 25 | private static readonly String Processing; 26 | private static readonly String Done; 27 | private static readonly String LableBoxTextEmpty; 28 | private static readonly String CheckBoxDeleteText; 29 | public static readonly String ButtonOKText; 30 | public static readonly String ButtonCancleText; 31 | public static readonly String ErrorPathMsg; 32 | public static readonly String DotCount; 33 | public static readonly String FormFixPathText; 34 | //MultiLang (English and Chinese Simplified) 35 | static FormMain() 36 | { 37 | if (System.Globalization.CultureInfo.InstalledUICulture.ThreeLetterISOLanguageName == "zho") 38 | { 39 | // Chinese Simplified 40 | Processing = "*** 处理中 ***"; 41 | Done = "*** 完成 ***"; 42 | LableBoxTextEmpty = "拖拽单个文件或文件夹到此处"; 43 | CheckBoxDeleteText = "删除"; 44 | ButtonOKText = "确定"; 45 | ButtonCancleText = "取消"; 46 | ErrorPathMsg = "路径未找到,它可能是一个以多个点号(.)结尾的文件夹,请输出点号数量:"; 47 | DotCount = "数量(2-99):"; 48 | FormFixPathText = "修改路径"; 49 | } 50 | else 51 | { 52 | Processing = "*** Processing ***"; 53 | Done = "*** Done ***"; 54 | LableBoxTextEmpty = "Drag and drop a file or a folder into me"; 55 | CheckBoxDeleteText = "Delete"; 56 | ButtonOKText = "OK"; 57 | ButtonCancleText = "Cancle"; 58 | ErrorPathMsg = "Path was not found, it may be a Directory end with Dot(.), please enter the count of Dot."; 59 | DotCount = "Count(2-99):"; 60 | FormFixPathText = "Modify the path"; 61 | } 62 | } 63 | 64 | public FormMain() 65 | { 66 | InitializeComponent(); 67 | ButtonOK.Text = ButtonOKText; 68 | CheckBoxDelete.Text = CheckBoxDeleteText; 69 | StatusChange(); 70 | } 71 | #endregion 72 | 73 | 74 | private enum Status 75 | { 76 | Start, 77 | Dropped, 78 | Processing, 79 | Finished 80 | } 81 | private void StatusChange(Status status = Status.Start, String advText = null) 82 | { 83 | switch (status) 84 | { 85 | case Status.Dropped: 86 | LabelPath.Text = advText; 87 | LabelTips.Text = string.Empty; 88 | CheckBoxDelete.Enabled = true; 89 | CheckBoxDelete.Checked = false; 90 | ButtonOK.Enabled = false; 91 | break; 92 | case Status.Processing: 93 | LabelTips.Focus(); 94 | LabelTips.Text = Processing; 95 | LabelPath.Enabled = false; 96 | CheckBoxDelete.Enabled = false; 97 | ButtonOK.Enabled = false; 98 | break; 99 | case Status.Finished: 100 | LabelTips.Text = Done; 101 | goto default; 102 | default: 103 | LabelPath.Enabled = true; 104 | LabelPath.Text = LableBoxTextEmpty; 105 | CheckBoxDelete.Enabled = false; 106 | CheckBoxDelete.Checked = false; 107 | ButtonOK.Enabled = false; 108 | break; 109 | } 110 | } 111 | 112 | private void CheckBoxDelete_CheckedChanged(object sender, EventArgs e) 113 | { 114 | ButtonOK.Enabled = CheckBoxDelete.Checked; 115 | } 116 | 117 | private String Path; 118 | 119 | private void LabelPath_DragDrop(object sender, DragEventArgs e) 120 | { 121 | var list = (String[])e.Data.GetData(DataFormats.FileDrop); 122 | if (list.Length == 1) 123 | { 124 | 125 | if (AdvancedDeletion.IsExists(list[0], out var b)) 126 | { 127 | Path = list[0]; 128 | StatusChange(Status.Dropped, Path); 129 | return; 130 | } 131 | else if (b && FPForm.ShowDialog(this) == DialogResult.OK) 132 | { 133 | Path = list[0] + FPForm.Dots; 134 | if (AdvancedDeletion.IsExists(Path, out b)) 135 | { 136 | StatusChange(Status.Dropped, Path); 137 | return; 138 | } 139 | } 140 | 141 | } 142 | StatusChange(); 143 | } 144 | private void LabelPath_DragEnter(object sender, DragEventArgs e) 145 | { 146 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 147 | { 148 | e.Effect = DragDropEffects.Link; 149 | } 150 | else 151 | { 152 | StatusChange(); 153 | e.Effect = DragDropEffects.None; 154 | } 155 | } 156 | 157 | private void ButtonOK_Click(object sender, EventArgs e) 158 | { 159 | StatusChange(Status.Processing); 160 | BackgroundWorkerDel.RunWorkerAsync(); 161 | } 162 | 163 | private void BackgroundWorkerDel_DoWork(object sender, DoWorkEventArgs e) 164 | { 165 | AdvancedDeletion.Delete(Path); 166 | } 167 | 168 | private void BackgroundWorkerDel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 169 | { 170 | StatusChange(Status.Finished); 171 | } 172 | 173 | 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/DeletionTool/FormMain.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 125 | 126 | AAABAAEAICAQAAEABADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAA 127 | AAAAAAAAgAAAAACAAACAgAAAAACAAIAAgAAAgIAAwMDAAICAgAD/AAAAAP8AAP//AAAAAP8A/wD/AAD/ 128 | /wD///8AAAAMzMAAAAAAAAAMzMAAAAAAzMzMAAAAAAAAzMzMAAAADMzMzMAAAAAADMzMzMAAAMzMzMzM 129 | AAAAAMzMzMzMAAzMzMzMzMAAAAzMzMzMzMDMzMzMzMzMAADMzMzMzMzMzMzMzMzMzMAMzMzMzMzMzMzM 130 | zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMDMzMzMzMzMzMzMzMzMzMwADMzMzMzMzMzMzMzMzM 131 | zAAADMzMzMzMzMzMzMzMzMAAAADMzMzMzMzMzMzMzMwAAAAADMzMzMzMzMzMzMzAAAAAAADMzMzMzMzM 132 | zMzMAAAAAAAADMzMzMzMzMzMwAAAAAAAAAzMzMzMzMzMzMAAAAAAAADMzMzMzMzMzMzMAAAAAAAMzMzM 133 | zMzMzMzMzMAAAAAAzMzMzMzMzMzMzMzMAAAADMzMzMzMzMzMzMzMzMAAAMzMzMzMzMzMzMzMzMzMAAzM 134 | zMzMzMzMzMzMzMzMzMDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzADMzMzMzM 135 | zMzMzMzMzMzMAADMzMzMzMzMDMzMzMzMwAAADMzMzMzMwADMzMzMzAAAAADMzMzMzAAADMzMzMAAAAAA 136 | DMzMzMAAAADMzMwAAAAAAADMzMwAAAAADMzAAAAAAAAADMzAAAD4f/4f8D/8D+Af+AfAD/ADgAfgAQAD 137 | wAAAAYAAAAAAAAAAAACAAAABwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//gAAf/wAAD/4AAAf8AAAD+AA 138 | AAfAAAADgAAAAQAAAAAAAAAAAAGAAAADwACAB+ABwA/wA+Af+AfwP/wP+H/+Hw== 139 | 140 | 141 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/AdvancedDeletion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | 12 | namespace YYProject.AdvancedDeletion 13 | { 14 | 15 | 16 | 17 | /// 18 | /// Provides a static class for file/directory deletion. 19 | /// Notice that this class is not complete, and very dependent on front-end. So it's unsuitable as an independent libary, unless there are enough judgement and error handling before(when) using it. 20 | /// 21 | public static class AdvancedDeletion 22 | { 23 | private const String _LongPathPrefix = @"\\?\"; //Long path prefix 24 | 25 | /// 26 | /// Delete a file or directory. 27 | /// 28 | /// The path of a file or a directory. 29 | public static void Delete(String path) 30 | { 31 | InnerDeleteObject(path); 32 | 33 | } 34 | 35 | /// 36 | /// Determines whether the specified path exists. 37 | /// 38 | /// Object path. 39 | /// Determines whether the specified path may end with some dots. 40 | /// 41 | public static Boolean IsExists(String path, out Boolean mayHasDot) 42 | { 43 | mayHasDot = false; 44 | if (NativeAPI.IsFileExist(@"\\?\" + path, out var error)) 45 | { 46 | return true; 47 | } 48 | if (error == NativeAPI.ERROR_FILE_NOT_FOUND) 49 | { 50 | mayHasDot = true; 51 | } 52 | return false; 53 | } 54 | 55 | private static void InnerDeleteObject(String path) 56 | { 57 | path = @"\\?\" + path; //UNC Path 58 | var objType = GetPathType(path); 59 | if (!objType.HasValue) 60 | { 61 | return; 62 | } 63 | 64 | var occupiedFiles = StringListPool.Rent(); 65 | var occupiedDirectories = StringListPool.Rent(); 66 | if (objType.Value.dwFileAttributes.HasFlag(FileAttributes.Directory)) 67 | { 68 | InnerDeleteDirectory(path, occupiedFiles, occupiedDirectories); 69 | } 70 | else 71 | { 72 | InnerDeleteFile(path, objType.Value.dwFileAttributes, occupiedFiles); 73 | DeleteOccupiedFiles(occupiedFiles); 74 | } 75 | StringListPool.Return(occupiedFiles); 76 | StringListPool.Return(occupiedDirectories); 77 | } 78 | // File or directory or invalid path? 79 | private static Win32FileAttributeData? GetPathType(String path) 80 | { 81 | if (NativeAPI.IsFileExist(path, out var error)) 82 | { 83 | if (NativeAPI.TryGetFileAttributes(path, out var fileAttributes)) 84 | { 85 | return fileAttributes; 86 | } 87 | } 88 | return null; 89 | } 90 | 91 | private static void InnerDeleteFile(String path, FileAttributes fileAttributes, List occupiedFiles) 92 | { 93 | if (fileAttributes.HasFlag(FileAttributes.ReadOnly)) 94 | { 95 | --fileAttributes; //deselect Read-Only 96 | NativeAPI.SetFileAttributes(path, fileAttributes); 97 | } 98 | if (!NativeAPI.DeleteFile(path, out var occupied) && occupied) 99 | { 100 | occupiedFiles.Add(path); 101 | } 102 | } 103 | 104 | //Notice that win api FindFirstFile does not support the path end with "\". 105 | private static void InnerDeleteDirectory(String path, List occupiedFiles, List occupiedDirectories) 106 | { 107 | var dirList = TraverseDirectory(path, occupiedFiles); // Traverse directory and delete files. 108 | DeleteOccupiedFiles(occupiedFiles); //Delete occupied files 109 | foreach (var item in dirList) //Delete directories. 110 | { 111 | var b= NativeAPI.RemoveDirectory(item,out var occupied); 112 | if (occupied) 113 | { 114 | occupiedDirectories.Add(item); 115 | } 116 | } 117 | DeleteOccupiedDirectories(dirList, occupiedDirectories); //Delete occupied directories. 118 | } 119 | 120 | private static Stack TraverseDirectory(String path, List occupiedFiles) 121 | { 122 | var paths = StringListPool.Rent(); 123 | var result = new Stack(); 124 | paths.Add(path); 125 | TraverseDirectoryPower(paths, result, occupiedFiles); 126 | return result; 127 | } 128 | 129 | private static void TraverseDirectoryPower(List paths, Stack allPaths, List occupiedFiles) 130 | { 131 | if (paths == null) 132 | { 133 | return; 134 | } 135 | Parallel.ForEach(paths, item => 136 | { 137 | allPaths.Push(item); 138 | TraverseDirectoryPower(GetDirectories(item,occupiedFiles), allPaths, occupiedFiles); 139 | }); 140 | StringListPool.Return(paths); 141 | } 142 | 143 | private static List GetDirectories(String path, List occupiedFiles) 144 | { 145 | List paths; 146 | String findPath; 147 | if (NativeAPI.TryFindFirstFile(path + @"\*", out var findHandle, out var foo)) // in 148 | { 149 | paths = StringListPool.Rent(); 150 | while (true) 151 | { 152 | if (!NativeAPI.TryFindNextFile(findHandle, out var findInfo)) 153 | { 154 | break; //error or end 155 | } 156 | findPath = path + @"\" + findInfo.cFileName; 157 | 158 | if (!findInfo.FileAttributes.dwFileAttributes.HasFlag(FileAttributes.Directory)) 159 | { 160 | InnerDeleteFile(findPath, findInfo.FileAttributes.dwFileAttributes, occupiedFiles); 161 | } 162 | else if (findInfo.cFileName != ".." && findInfo.cFileName != ".") //ignores ".." or "." . 163 | { 164 | paths.Add(findPath); 165 | 166 | } 167 | } 168 | } 169 | else 170 | { 171 | paths = null; 172 | } 173 | if (findHandle != null) 174 | { 175 | findHandle.Close(); 176 | } 177 | return paths.ToList(); 178 | } 179 | 180 | private static void DeleteOccupiedFiles(List occupiedFiles) 181 | { 182 | if (occupiedFiles.Count > 0) 183 | { 184 | Unlocker.ReleaseObjects(occupiedFiles.ToArray()); 185 | foreach (var item in occupiedFiles) 186 | { 187 | NativeAPI.DeleteFile(item, out var kd); 188 | } 189 | } 190 | 191 | } 192 | 193 | private static void DeleteOccupiedDirectories(Stack paths, List occupiedDirectories) 194 | { 195 | if (occupiedDirectories.Count > 0) 196 | { 197 | Unlocker.ReleaseObjects(occupiedDirectories.ToArray(),false); 198 | 199 | foreach (var item in paths) //all in list 200 | { 201 | NativeAPI.RemoveDirectory(item,out var foo); 202 | } 203 | 204 | } 205 | } 206 | 207 | 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Unlocker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | internal static class Unlocker 12 | { 13 | private static readonly Dictionary _DeviceNameMap; 14 | 15 | //determines whether it's a file/diretory handle. 16 | private static readonly Int32 _HandleTypeStringOffset = 0x58 + IntPtr.Size * 2; 17 | //Gets the file name of the file/diretory handle. 18 | private static readonly Int32 _FileNameStringOffset = IntPtr.Size * 2; 19 | private const String _DevicePre = @"\Device\HarddiskVolume"; //Hard disk only. 20 | private static readonly Int32 _HandleEntrySize = 8 + IntPtr.Size * 2; 21 | private static readonly Int32 _HandleInfoSize = _HandleEntrySize + IntPtr.Size; 22 | 23 | static Unlocker() 24 | { 25 | var drives = Environment.GetLogicalDrives(); 26 | _DeviceNameMap = new Dictionary(drives.Length); 27 | foreach (var item in drives) 28 | { 29 | string deviceName = item.Substring(0, 2); 30 | if (!NativeAPI.TryQueryDosDevice(deviceName, out var result)) 31 | { 32 | continue; 33 | } 34 | _DeviceNameMap.Add(result, deviceName); 35 | } 36 | } 37 | 38 | public static RmProcessInfo[] HolderList; 39 | 40 | public static void ReleaseObjects(String[] objectNames, Boolean IsFiles = true) 41 | { 42 | if (IsFiles) 43 | { 44 | HolderList = GetHolderList(objectNames); 45 | } 46 | if (HolderList == null) 47 | { 48 | return; 49 | } 50 | 51 | /*There's no need to define these structs, becouse we only need a little part of them. 52 | *http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle.htm 53 | *http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry.htm?ts=0,67 */ 54 | 55 | if (!NativeAPI.TryQuerySystemInformation(SystemInfomationClass.SystemHandleInformation, out var info, _HandleInfoSize)) 56 | { 57 | return; 58 | } 59 | 60 | #region X86 or X64 61 | Int32 count = IntPtr.Size == 4 ? Marshal.ReadInt32(info.DangerousGetHandle()) : (Int32)Marshal.ReadInt64(info.DangerousGetHandle()); 62 | var longHandles = info.DangerousGetHandle() + IntPtr.Size; 63 | #endregion 64 | 65 | Parallel.For(0, count, i => 66 | { 67 | var pid = Marshal.ReadInt32(longHandles, i * _HandleEntrySize); 68 | var handle = Marshal.ReadInt16(longHandles, i * _HandleEntrySize + 6); 69 | foreach (var item in HolderList) 70 | { 71 | if (pid == item.Process.ProcessId && IsObject(pid, (IntPtr)handle, objectNames)) 72 | { 73 | TryReleaseHandle(pid, (IntPtr)handle); 74 | } 75 | } 76 | //Parallel.ForEach(HolderList, item => 77 | //{ 78 | // if (pid == item.Process.ProcessId && IsObject(pid, (IntPtr)handle, objectNames)) 79 | // { 80 | // TryReleaseHandle(pid, (IntPtr)handle); 81 | // } 82 | //}); 83 | }); 84 | if (!IsFiles) 85 | { 86 | HolderList = null; 87 | } 88 | info.Close(); 89 | } 90 | 91 | 92 | private static RmProcessInfo[] GetHolderList(String[] fileNames) 93 | { 94 | try 95 | { 96 | RmHelper.SharedInstance.StartSession(); 97 | if (RmHelper.SharedInstance.TryGetHolderListOfFiles(fileNames, out var holderList)) 98 | { 99 | return holderList; 100 | }; 101 | return null; 102 | } 103 | finally 104 | { 105 | 106 | RmHelper.SharedInstance.EndSession(); 107 | } 108 | } 109 | 110 | //determines whether it's object. 111 | private static Boolean IsObject(Int32 pID, IntPtr remoteHandle, IEnumerable fileNames) 112 | { 113 | NativeNormalHandle handle = null; 114 | try 115 | { 116 | handle = HandleCopy(pID, remoteHandle); 117 | if (handle != null && IsFileOrDirectoryHandle(handle.DangerousGetHandle())) 118 | { 119 | var fileName = GetFileNameFromHandle(handle.DangerousGetHandle()); 120 | foreach (var item in fileNames) 121 | { 122 | if (item.Equals(fileName)) 123 | { 124 | return true; 125 | } 126 | } 127 | } 128 | return false; 129 | } 130 | finally 131 | { 132 | if (handle != null) 133 | { 134 | handle.Close(); 135 | } 136 | } 137 | 138 | } 139 | 140 | private static Boolean TryReleaseHandle(Int32 pID, IntPtr remoteHandle) 141 | { 142 | NativeNormalHandle handle = null; 143 | try 144 | { 145 | handle = HandleCopy(pID, remoteHandle, true); 146 | if (handle != null) 147 | { 148 | 149 | return true; 150 | } 151 | return false; 152 | } 153 | finally 154 | { 155 | if (handle != null) 156 | { 157 | handle.Close(); 158 | } 159 | 160 | } 161 | 162 | } 163 | 164 | private static NativeNormalHandle HandleCopy(Int32 pID, IntPtr remoteHandle, Boolean removeSourceHandle = false) 165 | { 166 | NativeNormalHandle pHandle = null; 167 | try 168 | { 169 | if (NativeAPI.TryOpenProcess(pID, out pHandle) && NativeAPI.TryDuplicateHandle(pHandle, remoteHandle, NativeAPI.GetCurrentProcess(), out var lHandle, removeSourceHandle)) 170 | { 171 | return lHandle; 172 | } 173 | return null; 174 | } 175 | 176 | finally 177 | { 178 | if (pHandle != null) 179 | { 180 | pHandle.Close(); 181 | } 182 | } 183 | } 184 | 185 | private static Boolean IsFileOrDirectoryHandle(IntPtr localHandle) 186 | { 187 | AllocatedMemoryHandle handleType = null; 188 | try 189 | { 190 | 191 | if (NativeAPI.TryNtQueryObject(localHandle, ObjectInfoamtionClass.ObjectTypeInformation, out handleType)) 192 | { 193 | //https://msdn.microsoft.com/en-us/library/bb432383( 194 | var length = Marshal.ReadInt16(handleType.DangerousGetHandle()) >> 1; 195 | var result = Marshal.PtrToStringUni(handleType.DangerousGetHandle() + _HandleTypeStringOffset, length); 196 | return result.Equals("File") || result.Equals("Directory"); 197 | } 198 | return false; 199 | } 200 | finally 201 | { 202 | if (handleType != null) 203 | { 204 | handleType.Close(); 205 | } 206 | } 207 | 208 | } 209 | 210 | private static String GetFileNameFromHandle(IntPtr localHandle) 211 | { 212 | AllocatedMemoryHandle handleType = null; 213 | try 214 | { 215 | if (NativeAPI.TryNtQueryObject(localHandle, ObjectInfoamtionClass.ObjectNameInformation, out handleType)) 216 | { 217 | //https://msdn.microsoft.com/en-us/library/windows/hardware/ff550990 218 | var length = Marshal.ReadInt16(handleType.DangerousGetHandle()) >> 1; 219 | var result = Marshal.PtrToStringUni(handleType.DangerousGetHandle() + _FileNameStringOffset, length); 220 | if (result.LastIndexOf(_DevicePre) != 0) 221 | { 222 | return null; 223 | 224 | } 225 | var dosName = result.Substring(0, result.IndexOf(@"\", _DevicePre.Length)); 226 | var ret = _DeviceNameMap.TryGetValue(dosName, out var ntName); 227 | if (!ret || !dosName.StartsWith(_DevicePre)) 228 | { 229 | return null; 230 | } 231 | return @"\\?\" + result.Replace(dosName, ntName); 232 | } 233 | return null; 234 | } 235 | catch 236 | { 237 | return null; 238 | } 239 | finally 240 | { 241 | if (handleType != null) 242 | { 243 | handleType.Close(); 244 | } 245 | } 246 | 247 | } 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/NativeAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | internal static class NativeAPI 12 | { 13 | #region Win32APIs 14 | 15 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 16 | [return: MarshalAs(UnmanagedType.Bool)] 17 | private static extern Boolean GetFileAttributesExW(String lpFileName, GetFileExInfoLevels fInfoLevelId, out Win32FileAttributeData lpFileInformation); 18 | [DllImport("kernel32.dll", SetLastError = true)] 19 | [return: MarshalAs(UnmanagedType.Bool)] 20 | private static extern Boolean FindClose(IntPtr hFindFile); 21 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 22 | private static extern NativeFindFileHandle FindFirstFileExW(String lpFileName, FindExInfoLevels fInfoLevelId, out Win32FindData lpFindFileData, FindExSearchOps fSearchOp, IntPtr lpSearchFilter, AdditionalFlags dwAdditionalFlags); 23 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 24 | [return: MarshalAs(UnmanagedType.Bool)] 25 | private static extern Boolean FindNextFileW(IntPtr hFindFile, out Win32FindData lpFindFileData); 26 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 27 | [return: MarshalAs(UnmanagedType.Bool)] 28 | private static extern Boolean DeleteFileW(String lpFileName); 29 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 30 | [return: MarshalAs(UnmanagedType.Bool)] 31 | private static extern Boolean RemoveDirectoryW(String lpPathName); 32 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 33 | [return: MarshalAs(UnmanagedType.Bool)] 34 | private static extern Boolean SetFileAttributesW(String lpFileName, FileAttributes dwFileAttributes); 35 | [DllImport("kernel32.dll", SetLastError = true)] 36 | [return: MarshalAs(UnmanagedType.Bool)] 37 | private static extern Boolean QueryDosDevice(String lpDeviceName, StringBuilder lpTargetPath, Int32 ucchMax); 38 | [DllImport("ntdll.dll")] 39 | private static extern NtStatus NtQuerySystemInformation(SystemInfomationClass InfoClass, [Out] IntPtr Info, Int32 Size, out Int32 Length); 40 | [DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true)] 41 | [return: MarshalAs(UnmanagedType.Bool)] 42 | private static extern Boolean NativeCloseHandle(IntPtr hObject); 43 | [DllImport("kernel32.dll", SetLastError = true)] 44 | private static extern NativeNormalHandle OpenProcess(ProcessAccessFlags processAccess, Boolean bInheritHandle, Int32 processId); 45 | [DllImport("kernel32.dll", SetLastError = true)] 46 | [return: MarshalAs(UnmanagedType.Bool)] 47 | private static extern Boolean DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out NativeNormalHandle lpTargetHandle, UInt32 dwDesiredAccess, Boolean bInheritHandle, DuplicateOptions dwOptions); 48 | [DllImport("ntdll.dll")] 49 | private static extern NtStatus NtQueryObject(IntPtr objectHandle, ObjectInfoamtionClass informationClass, [Out] IntPtr informationPtr, Int32 informationLength, out Int32 Length); 50 | [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode)] 51 | private static extern Int32 RmRegisterResources(UInt32 dwSessionHandle, UInt32 nFiles, String[] rgsFilenames, UInt32 nApplications, RmUniqueProcess[] rgApplications, UInt32 nServices, String[] rgsServiceNames); 52 | [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode)] 53 | private static extern Int32 RmGetList(UInt32 dwSessionHandle, out UInt32 pnProcInfoNeeded, ref UInt32 pnProcInfo, [Out] RmProcessInfo[] rgAffectedApps, out RmRebootReason lpdwRebootReasons); 54 | [DllImport("rstrtmgr.dll", EntryPoint = "RmEndSession")] 55 | private static extern Int32 NativeRmEndSession(UInt32 pSessionHandle); 56 | [DllImport("Rstrtmgr.dll")] 57 | private static extern Int32 RmStartSession(out UInt32 pSessionHandle, UInt32 dwSessionFlags, StringBuilder strSessionKey); 58 | [DllImport("kernel32.dll")] 59 | public static extern IntPtr GetCurrentProcess(); 60 | 61 | #endregion 62 | 63 | #region Win32ErrorCodes 64 | private const Int32 ERROR_SHARING_VIOLATION = 0x20; 65 | private const Int32 NO_MORE_FILES = 0x12; //It's not an error. 66 | public const Int32 ERROR_FILE_NOT_FOUND = 0x2; 67 | public const Int32 ERROR_PATH_NOT_FOUND = 0x3; 68 | private const Int32 ERROR_MORE_DATA = 234; 69 | #endregion 70 | 71 | 72 | 73 | private static StringBuilder _DosDeviceName = new StringBuilder(260); //thread-safe in this project. 74 | 75 | 76 | public static Boolean TryRmStartSession(out UInt32 sessionHandle, out String sessionKey) 77 | { 78 | var session = new StringBuilder(Marshal.SizeOf(Guid.NewGuid()) * 2 + 1); 79 | var error = RmStartSession(out sessionHandle, 0, session); 80 | sessionKey = session.ToString(); 81 | return error == 0 ? true : false; 82 | } 83 | 84 | public static Boolean TryRmEndSession(UInt32 pSessionHandle) 85 | { 86 | return NativeRmEndSession(pSessionHandle) == 0 ? true : false; 87 | } 88 | 89 | public static Boolean TryRmGetList(UInt32 sessionHandle, out RmRebootReason rebootReasons, out RmProcessInfo[] affectedApps) 90 | { 91 | affectedApps = null; 92 | var nCount = 0U; 93 | var error = RmGetList(sessionHandle, out var nlength, ref nCount, affectedApps, out rebootReasons); 94 | while (error == ERROR_MORE_DATA) 95 | { 96 | affectedApps = new RmProcessInfo[nlength]; 97 | nCount = (UInt32)affectedApps.Length; 98 | error = RmGetList(sessionHandle, out nlength, ref nCount, affectedApps, out rebootReasons); 99 | } 100 | return error == 0 ? true : false; 101 | } 102 | 103 | public static Boolean TryRmRegisterResources(UInt32 dwSessionHandle, String[] rgsFilenames, RmUniqueProcess[] rgApplications, String[] rgsServiceNames) 104 | { 105 | 106 | var error = RmRegisterResources(dwSessionHandle, 107 | rgsFilenames == null ? 0 : (UInt32)rgsFilenames.Length, rgsFilenames, 108 | rgApplications == null ? 0 : (UInt32)rgApplications.Length, rgApplications, 109 | rgsServiceNames == null ? 0 : (UInt32)rgsServiceNames.Length, rgsServiceNames); 110 | return error == 0 ? true : false; 111 | } 112 | 113 | public static Boolean TryNtQueryObject(IntPtr objectHandle, ObjectInfoamtionClass informationClass, out AllocatedMemoryHandle informationPtr, Int32 startSize = 0) 114 | { 115 | informationPtr = new AllocatedMemoryHandle(startSize); 116 | var info = NtQueryObject(objectHandle, informationClass, informationPtr.DangerousGetHandle(), informationPtr.Size, out var actualSize); 117 | if (info == NtStatus.InvalidHandle) 118 | { 119 | if (informationPtr.IsInvalid) informationPtr.Close(); 120 | informationPtr = null; 121 | return false; 122 | } 123 | while (info == NtStatus.InfoLengthMismatch) 124 | { 125 | informationPtr.ChangeMemorySize(actualSize); 126 | info = NtQueryObject(objectHandle, informationClass, informationPtr.DangerousGetHandle(), informationPtr.Size, out actualSize); 127 | } 128 | if (info != NtStatus.Success) 129 | { 130 | if (informationPtr.IsInvalid) informationPtr.Close(); 131 | informationPtr = null; 132 | return false; 133 | } 134 | return true; 135 | } 136 | 137 | public static Boolean TryDuplicateHandle(NativeNormalHandle sourceProcessHandle, IntPtr sourceHandle, IntPtr targetProcessHandle, out NativeNormalHandle targetHandle, Boolean removeSourceHandle = false) 138 | { 139 | if (!DuplicateHandle(sourceProcessHandle.DangerousGetHandle(), sourceHandle, targetProcessHandle, out targetHandle, 0, false, DuplicateOptions.DuplicateSameAccess | (removeSourceHandle ? DuplicateOptions.DuplicateCloseSource : DuplicateOptions.None))) 140 | { 141 | if (targetHandle.IsInvalid) 142 | { 143 | targetHandle.Close(); 144 | } 145 | targetHandle = null; 146 | return false; 147 | } 148 | return true; 149 | } 150 | 151 | public static Boolean TryOpenProcess(Int32 pID, out NativeNormalHandle handle, Boolean inheritHandle = false) 152 | { 153 | handle = OpenProcess(ProcessAccessFlags.All, inheritHandle, pID); 154 | if (handle.IsInvalid) 155 | { 156 | handle = null; 157 | return false; 158 | } 159 | return true; 160 | } 161 | 162 | public static Boolean TryCloseHandle(IntPtr handle) 163 | { 164 | return NativeCloseHandle(handle); 165 | } 166 | 167 | public static Boolean TryQuerySystemInformation(SystemInfomationClass infoClass, out AllocatedMemoryHandle infoHandle, Int32 startSize = 0) 168 | { 169 | infoHandle = new AllocatedMemoryHandle(startSize); 170 | var info = NtQuerySystemInformation(infoClass, infoHandle.DangerousGetHandle(), infoHandle.Size, out var actualSize); 171 | while (info == NtStatus.InfoLengthMismatch) 172 | { 173 | infoHandle.ChangeMemorySize(actualSize); 174 | info = NativeAPI.NtQuerySystemInformation(infoClass, infoHandle.DangerousGetHandle(), infoHandle.Size, out actualSize); 175 | } 176 | if (info != NtStatus.Success) 177 | { 178 | if (infoHandle.IsInvalid) 179 | { 180 | infoHandle.Close(); 181 | } 182 | infoHandle = null; 183 | return false; 184 | } 185 | return true; 186 | 187 | } 188 | 189 | public static Boolean TryQueryDosDevice(String ntDeviceName, out String result) 190 | { 191 | result = null; 192 | _DosDeviceName.Clear(); 193 | if (!QueryDosDevice(ntDeviceName, _DosDeviceName, _DosDeviceName.Capacity)) 194 | { 195 | return false; 196 | } 197 | result = _DosDeviceName.ToString(); 198 | return true; 199 | } 200 | 201 | public static Boolean SetFileAttributes(String path, FileAttributes fileAttributes) 202 | { 203 | return SetFileAttributesW(path, fileAttributes); 204 | } 205 | 206 | public static Boolean TryGetFileAttributes(String path, out Win32FileAttributeData fileAttribute) 207 | { 208 | return GetFileAttributesExW(path, GetFileExInfoLevels.GetFileExInfoStandard, out fileAttribute); 209 | } 210 | 211 | public static Boolean TryCloseFindHandle(IntPtr findHandle) 212 | { 213 | return FindClose(findHandle); 214 | } 215 | 216 | public static Boolean TryFindFirstFile(String path, out NativeFindFileHandle findHandle, out Win32FindData findData) 217 | { 218 | findHandle = FindFirstFileExW(path, FindExInfoLevels.FindExInfoBasic, out findData, FindExSearchOps.FindExSearchNameMatch, IntPtr.Zero, AdditionalFlags.FindFirstEXLargeFetch); 219 | if (findHandle.IsInvalid) 220 | { 221 | findHandle = null; 222 | return false; 223 | } 224 | return true; 225 | } 226 | 227 | public static Boolean IsFileExist(String path, out Int32 error) 228 | { 229 | error = 0; 230 | using (var handle = FindFirstFileExW(path, FindExInfoLevels.FindExInfoBasic, out var findData, FindExSearchOps.FindExSearchNameMatch, IntPtr.Zero, AdditionalFlags.FindFirstEXLargeFetch)) 231 | { 232 | if (handle.IsInvalid) 233 | { 234 | error = Marshal.GetLastWin32Error(); 235 | return false; 236 | } 237 | return true; 238 | } 239 | } 240 | 241 | public static Boolean TryFindNextFile(NativeFindFileHandle findHandle, out Win32FindData findData) 242 | { 243 | if (!FindNextFileW(findHandle.DangerousGetHandle(), out findData)) 244 | { 245 | var error = Marshal.GetLastWin32Error(); 246 | findData.NoMoreFiles = error == NO_MORE_FILES; 247 | return false; 248 | } 249 | else 250 | { 251 | findData.NoMoreFiles = false; 252 | } 253 | return true; 254 | } 255 | 256 | public static Boolean DeleteFile(String path) 257 | { 258 | return DeleteFileW(path); 259 | } 260 | 261 | public static Boolean DeleteFile(String path, out Boolean isOccupied) 262 | { 263 | if (!DeleteFileW(path)) 264 | { 265 | var error = Marshal.GetLastWin32Error(); 266 | if (error == ERROR_SHARING_VIOLATION) 267 | { 268 | isOccupied = true; 269 | } 270 | else 271 | { 272 | isOccupied = false; 273 | } 274 | return false; 275 | } 276 | isOccupied = false; 277 | return true; 278 | } 279 | 280 | 281 | public static Boolean RemoveDirectory(String path, out Boolean isOccupied) 282 | { 283 | if (!RemoveDirectoryW(path)) 284 | { 285 | var error = Marshal.GetLastWin32Error(); 286 | if (error == ERROR_SHARING_VIOLATION) 287 | { 288 | isOccupied = true; 289 | } 290 | else 291 | { 292 | isOccupied = false; 293 | } 294 | return false; 295 | 296 | } 297 | isOccupied = false; 298 | return true; 299 | } 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /src/DeletionTool/AdvancedDeletion/Utilities/Win32API/NativeTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace YYProject.AdvancedDeletion 10 | { 11 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 12 | internal struct Win32FindData 13 | { 14 | public Win32FileAttributeData FileAttributes; 15 | public UInt32 dwReserved0; 16 | public UInt32 dwReserved1; 17 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 18 | public String cFileName; 19 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] 20 | public String cAlternateFileName; 21 | [NonSerialized] 22 | public Boolean NoMoreFiles; 23 | } 24 | [StructLayout(LayoutKind.Sequential)] 25 | internal struct Win32FileAttributeData 26 | { 27 | public FileAttributes dwFileAttributes; 28 | public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; 29 | public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; 30 | public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; 31 | public UInt32 nFileSizeHigh; 32 | public UInt32 nFileSizeLow; 33 | } 34 | internal enum GetFileExInfoLevels 35 | { 36 | GetFileExInfoStandard, 37 | GetFileExMaxInfoLevel 38 | } 39 | internal enum FindExInfoLevels 40 | { 41 | FindExInfoStandard, 42 | FindExInfoBasic, 43 | FindExInfoMaxInfoLevel 44 | } 45 | internal enum FindExSearchOps 46 | { 47 | FindExSearchNameMatch, 48 | FindExSearchLimitToDirectories, 49 | FindExSearchLimitToDevices 50 | } 51 | [Flags] 52 | internal enum AdditionalFlags 53 | { 54 | FindFirstEXCaseSensitive = 1, 55 | FindFirstEXLargeFetch = 2 56 | } 57 | internal enum SystemInfomationClass 58 | { 59 | SystemBasicInformation = 0x0000, 60 | SystemProcessorInformation = 0x0001, 61 | SystemPerformanceInformation = 0x0002, 62 | SystemTimeOfDayInformation = 0x0003, 63 | SystemPathInformation = 0x0004, 64 | SystemProcessInformation = 0x0005, 65 | SystemCallCountInformation = 0x0006, 66 | SystemDeviceInformation = 0x0007, 67 | SystemProcessorPerformanceInformation = 0x0008, 68 | SystemFlagsInformation = 0x0009, 69 | SystemCallTimeInformation = 0x000A, 70 | SystemModuleInformation = 0x000B, 71 | SystemLocksInformation = 0x000C, 72 | SystemStackTraceInformation = 0x000D, 73 | SystemPagedPoolInformation = 0x000E, 74 | SystemNonPagedPoolInformation = 0x000F, 75 | SystemHandleInformation = 0x0010, 76 | SystemObjectInformation = 0x0011, 77 | SystemPageFileInformation = 0x0012, 78 | SystemVdmInstemulInformation = 0x0013, 79 | SystemVdmBopInformation = 0x0014, 80 | SystemFileCacheInformation = 0x0015, 81 | SystemPoolTagInformation = 0x0016, 82 | SystemInterruptInformation = 0x0017, 83 | SystemDpcBehaviorInformation = 0x0018, 84 | SystemFullMemoryInformation = 0x0019, 85 | SystemLoadGdiDriverInformation = 0x001A, 86 | SystemUnloadGdiDriverInformation = 0x001B, 87 | SystemTimeAdjustmentInformation = 0x001C, 88 | SystemSummaryMemoryInformation = 0x001D, 89 | SystemMirrorMemoryInformation = 0x001E, 90 | SystemPerformanceTraceInformation = 0x001F, 91 | SystemCrashDumpInformation = 0x0020, 92 | SystemExceptionInformation = 0x0021, 93 | SystemCrashDumpStateInformation = 0x0022, 94 | SystemKernelDebuggerInformation = 0x0023, 95 | SystemContextSwitchInformation = 0x0024, 96 | SystemRegistryQuotaInformation = 0x0025, 97 | SystemExtendServiceTableInformation = 0x0026, 98 | SystemPrioritySeperation = 0x0027, 99 | SystemVerifierAddDriverInformation = 0x0028, 100 | SystemVerifierRemoveDriverInformation = 0x0029, 101 | SystemProcessorIdleInformation = 0x002A, 102 | SystemLegacyDriverInformation = 0x002B, 103 | SystemCurrentTimeZoneInformation = 0x002C, 104 | SystemLookasideInformation = 0x002D, 105 | SystemTimeSlipNotification = 0x002E, 106 | SystemSessionCreate = 0x002F, 107 | SystemSessionDetach = 0x0030, 108 | SystemSessionInformation = 0x0031, 109 | SystemRangeStartInformation = 0x0032, 110 | SystemVerifierInformation = 0x0033, 111 | SystemVerifierThunkExtend = 0x0034, 112 | SystemSessionProcessInformation = 0x0035, 113 | SystemLoadGdiDriverInSystemSpace = 0x0036, 114 | SystemNumaProcessorMap = 0x0037, 115 | SystemPrefetcherInformation = 0x0038, 116 | SystemExtendedProcessInformation = 0x0039, 117 | SystemRecommendedSharedDataAlignment = 0x003A, 118 | SystemComPlusPackage = 0x003B, 119 | SystemNumaAvailableMemory = 0x003C, 120 | SystemProcessorPowerInformation = 0x003D, 121 | SystemEmulationBasicInformation = 0x003E, 122 | SystemEmulationProcessorInformation = 0x003F, 123 | SystemExtendedHandleInformation = 0x0040, 124 | SystemLostDelayedWriteInformation = 0x0041, 125 | SystemBigPoolInformation = 0x0042, 126 | SystemSessionPoolTagInformation = 0x0043, 127 | SystemSessionMappedViewInformation = 0x0044, 128 | SystemHotpatchInformation = 0x0045, 129 | SystemObjectSecurityMode = 0x0046, 130 | SystemWatchdogTimerHandler = 0x0047, 131 | SystemWatchdogTimerInformation = 0x0048, 132 | SystemLogicalProcessorInformation = 0x0049, 133 | SystemWow64SharedInformationObsolete = 0x004A, 134 | SystemRegisterFirmwareTableInformationHandler = 0x004B, 135 | SystemFirmwareTableInformation = 0x004C, 136 | SystemModuleInformationEx = 0x004D, 137 | SystemVerifierTriageInformation = 0x004E, 138 | SystemSuperfetchInformation = 0x004F, 139 | SystemMemoryListInformation = 0x0050, // SYSTEM_MEMORY_LIST_INFORMATION 140 | SystemFileCacheInformationEx = 0x0051, 141 | SystemThreadPriorityClientIdInformation = 0x0052, 142 | SystemProcessorIdleCycleTimeInformation = 0x0053, 143 | SystemVerifierCancellationInformation = 0x0054, 144 | SystemProcessorPowerInformationEx = 0x0055, 145 | SystemRefTraceInformation = 0x0056, 146 | SystemSpecialPoolInformation = 0x0057, 147 | SystemProcessIdInformation = 0x0058, 148 | SystemErrorPortInformation = 0x0059, 149 | SystemBootEnvironmentInformation = 0x005A, 150 | SystemHypervisorInformation = 0x005B, 151 | SystemVerifierInformationEx = 0x005C, 152 | SystemTimeZoneInformation = 0x005D, 153 | SystemImageFileExecutionOptionsInformation = 0x005E, 154 | SystemCoverageInformation = 0x005F, 155 | SystemPrefetchPatchInformation = 0x0060, 156 | SystemVerifierFaultsInformation = 0x0061, 157 | SystemSystemPartitionInformation = 0x0062, 158 | SystemSystemDiskInformation = 0x0063, 159 | SystemProcessorPerformanceDistribution = 0x0064, 160 | SystemNumaProximityNodeInformation = 0x0065, 161 | SystemDynamicTimeZoneInformation = 0x0066, 162 | SystemCodeIntegrityInformation = 0x0067, 163 | SystemProcessorMicrocodeUpdateInformation = 0x0068, 164 | SystemProcessorBrandString = 0x0069, 165 | SystemVirtualAddressInformation = 0x006A, 166 | SystemLogicalProcessorAndGroupInformation = 0x006B, 167 | SystemProcessorCycleTimeInformation = 0x006C, 168 | SystemStoreInformation = 0x006D, 169 | SystemRegistryAppendString = 0x006E, 170 | SystemAitSamplingValue = 0x006F, 171 | SystemVhdBootInformation = 0x0070, 172 | SystemCpuQuotaInformation = 0x0071, 173 | SystemNativeBasicInformation = 0x0072, 174 | SystemErrorPortTimeouts = 0x0073, 175 | SystemLowPriorityIoInformation = 0x0074, 176 | SystemBootEntropyInformation = 0x0075, 177 | SystemVerifierCountersInformation = 0x0076, 178 | SystemPagedPoolInformationEx = 0x0077, 179 | SystemSystemPtesInformationEx = 0x0078, 180 | SystemNodeDistanceInformation = 0x0079, 181 | SystemAcpiAuditInformation = 0x007A, 182 | SystemBasicPerformanceInformation = 0x007B, 183 | SystemQueryPerformanceCounterInformation = 0x007C, 184 | SystemSessionBigPoolInformation = 0x007D, 185 | SystemBootGraphicsInformation = 0x007E, 186 | SystemScrubPhysicalMemoryInformation = 0x007F, 187 | SystemBadPageInformation = 0x0080, 188 | SystemProcessorProfileControlArea = 0x0081, 189 | SystemCombinePhysicalMemoryInformation = 0x0082, 190 | SystemEntropyInterruptTimingInformation = 0x0083, 191 | SystemConsoleInformation = 0x0084, 192 | SystemPlatformBinaryInformation = 0x0085, 193 | SystemThrottleNotificationInformation = 0x0086, 194 | SystemHypervisorProcessorCountInformation = 0x0087, 195 | SystemDeviceDataInformation = 0x0088, 196 | SystemDeviceDataEnumerationInformation = 0x0089, 197 | SystemMemoryTopologyInformation = 0x008A, 198 | SystemMemoryChannelInformation = 0x008B, 199 | SystemBootLogoInformation = 0x008C, 200 | SystemProcessorPerformanceInformationEx = 0x008D, 201 | SystemSpare0 = 0x008E, 202 | SystemSecureBootPolicyInformation = 0x008F, 203 | SystemPageFileInformationEx = 0x0090, 204 | SystemSecureBootInformation = 0x0091, 205 | SystemEntropyInterruptTimingRawInformation = 0x0092, 206 | SystemPortableWorkspaceEfiLauncherInformation = 0x0093, 207 | SystemFullProcessInformation = 0x0094, 208 | MaxSystemInfoClass = 0x0095 209 | } 210 | internal enum NtStatus : UInt32 211 | { 212 | // Success 213 | Success = 0x00000000, 214 | Wait0 = 0x00000000, 215 | Wait1 = 0x00000001, 216 | Wait2 = 0x00000002, 217 | Wait3 = 0x00000003, 218 | Wait63 = 0x0000003f, 219 | Abandoned = 0x00000080, 220 | AbandonedWait0 = 0x00000080, 221 | AbandonedWait1 = 0x00000081, 222 | AbandonedWait2 = 0x00000082, 223 | AbandonedWait3 = 0x00000083, 224 | AbandonedWait63 = 0x000000bf, 225 | UserApc = 0x000000c0, 226 | KernelApc = 0x00000100, 227 | Alerted = 0x00000101, 228 | Timeout = 0x00000102, 229 | Pending = 0x00000103, 230 | Reparse = 0x00000104, 231 | MoreEntries = 0x00000105, 232 | NotAllAssigned = 0x00000106, 233 | SomeNotMapped = 0x00000107, 234 | OpLockBreakInProgress = 0x00000108, 235 | VolumeMounted = 0x00000109, 236 | RxActCommitted = 0x0000010a, 237 | NotifyCleanup = 0x0000010b, 238 | NotifyEnumDir = 0x0000010c, 239 | NoQuotasForAccount = 0x0000010d, 240 | PrimaryTransportConnectFailed = 0x0000010e, 241 | PageFaultTransition = 0x00000110, 242 | PageFaultDemandZero = 0x00000111, 243 | PageFaultCopyOnWrite = 0x00000112, 244 | PageFaultGuardPage = 0x00000113, 245 | PageFaultPagingFile = 0x00000114, 246 | CrashDump = 0x00000116, 247 | ReparseObject = 0x00000118, 248 | NothingToTerminate = 0x00000122, 249 | ProcessNotInJob = 0x00000123, 250 | ProcessInJob = 0x00000124, 251 | ProcessCloned = 0x00000129, 252 | FileLockedWithOnlyReaders = 0x0000012a, 253 | FileLockedWithWriters = 0x0000012b, 254 | 255 | // Informational 256 | Informational = 0x40000000, 257 | ObjectNameExists = 0x40000000, 258 | ThreadWasSuspended = 0x40000001, 259 | WorkingSetLimitRange = 0x40000002, 260 | ImageNotAtBase = 0x40000003, 261 | RegistryRecovered = 0x40000009, 262 | 263 | // Warning 264 | Warning = 0x80000000, 265 | GuardPageViolation = 0x80000001, 266 | DatatypeMisalignment = 0x80000002, 267 | Breakpoint = 0x80000003, 268 | SingleStep = 0x80000004, 269 | BufferOverflow = 0x80000005, 270 | NoMoreFiles = 0x80000006, 271 | HandlesClosed = 0x8000000a, 272 | PartialCopy = 0x8000000d, 273 | DeviceBusy = 0x80000011, 274 | InvalidEaName = 0x80000013, 275 | EaListInconsistent = 0x80000014, 276 | NoMoreEntries = 0x8000001a, 277 | LongJump = 0x80000026, 278 | DllMightBeInsecure = 0x8000002b, 279 | 280 | // Error 281 | Error = 0xc0000000, 282 | Unsuccessful = 0xc0000001, 283 | NotImplemented = 0xc0000002, 284 | InvalidInfoClass = 0xc0000003, 285 | InfoLengthMismatch = 0xc0000004, 286 | AccessViolation = 0xc0000005, 287 | InPageError = 0xc0000006, 288 | PagefileQuota = 0xc0000007, 289 | InvalidHandle = 0xc0000008, 290 | BadInitialStack = 0xc0000009, 291 | BadInitialPc = 0xc000000a, 292 | InvalidCid = 0xc000000b, 293 | TimerNotCanceled = 0xc000000c, 294 | InvalidParameter = 0xc000000d, 295 | NoSuchDevice = 0xc000000e, 296 | NoSuchFile = 0xc000000f, 297 | InvalidDeviceRequest = 0xc0000010, 298 | EndOfFile = 0xc0000011, 299 | WrongVolume = 0xc0000012, 300 | NoMediaInDevice = 0xc0000013, 301 | NoMemory = 0xc0000017, 302 | NotMappedView = 0xc0000019, 303 | UnableToFreeVm = 0xc000001a, 304 | UnableToDeleteSection = 0xc000001b, 305 | IllegalInstruction = 0xc000001d, 306 | AlreadyCommitted = 0xc0000021, 307 | AccessDenied = 0xc0000022, 308 | BufferTooSmall = 0xc0000023, 309 | ObjectTypeMismatch = 0xc0000024, 310 | NonContinuableException = 0xc0000025, 311 | BadStack = 0xc0000028, 312 | NotLocked = 0xc000002a, 313 | NotCommitted = 0xc000002d, 314 | InvalidParameterMix = 0xc0000030, 315 | ObjectNameInvalid = 0xc0000033, 316 | ObjectNameNotFound = 0xc0000034, 317 | ObjectNameCollision = 0xc0000035, 318 | ObjectPathInvalid = 0xc0000039, 319 | ObjectPathNotFound = 0xc000003a, 320 | ObjectPathSyntaxBad = 0xc000003b, 321 | DataOverrun = 0xc000003c, 322 | DataLate = 0xc000003d, 323 | DataError = 0xc000003e, 324 | CrcError = 0xc000003f, 325 | SectionTooBig = 0xc0000040, 326 | PortConnectionRefused = 0xc0000041, 327 | InvalidPortHandle = 0xc0000042, 328 | SharingViolation = 0xc0000043, 329 | QuotaExceeded = 0xc0000044, 330 | InvalidPageProtection = 0xc0000045, 331 | MutantNotOwned = 0xc0000046, 332 | SemaphoreLimitExceeded = 0xc0000047, 333 | PortAlreadySet = 0xc0000048, 334 | SectionNotImage = 0xc0000049, 335 | SuspendCountExceeded = 0xc000004a, 336 | ThreadIsTerminating = 0xc000004b, 337 | BadWorkingSetLimit = 0xc000004c, 338 | IncompatibleFileMap = 0xc000004d, 339 | SectionProtection = 0xc000004e, 340 | EasNotSupported = 0xc000004f, 341 | EaTooLarge = 0xc0000050, 342 | NonExistentEaEntry = 0xc0000051, 343 | NoEasOnFile = 0xc0000052, 344 | EaCorruptError = 0xc0000053, 345 | FileLockConflict = 0xc0000054, 346 | LockNotGranted = 0xc0000055, 347 | DeletePending = 0xc0000056, 348 | CtlFileNotSupported = 0xc0000057, 349 | UnknownRevision = 0xc0000058, 350 | RevisionMismatch = 0xc0000059, 351 | InvalidOwner = 0xc000005a, 352 | InvalidPrimaryGroup = 0xc000005b, 353 | NoImpersonationToken = 0xc000005c, 354 | CantDisableMandatory = 0xc000005d, 355 | NoLogonServers = 0xc000005e, 356 | NoSuchLogonSession = 0xc000005f, 357 | NoSuchPrivilege = 0xc0000060, 358 | PrivilegeNotHeld = 0xc0000061, 359 | InvalidAccountName = 0xc0000062, 360 | UserExists = 0xc0000063, 361 | NoSuchUser = 0xc0000064, 362 | GroupExists = 0xc0000065, 363 | NoSuchGroup = 0xc0000066, 364 | MemberInGroup = 0xc0000067, 365 | MemberNotInGroup = 0xc0000068, 366 | LastAdmin = 0xc0000069, 367 | WrongPassword = 0xc000006a, 368 | IllFormedPassword = 0xc000006b, 369 | PasswordRestriction = 0xc000006c, 370 | LogonFailure = 0xc000006d, 371 | AccountRestriction = 0xc000006e, 372 | InvalidLogonHours = 0xc000006f, 373 | InvalidWorkstation = 0xc0000070, 374 | PasswordExpired = 0xc0000071, 375 | AccountDisabled = 0xc0000072, 376 | NoneMapped = 0xc0000073, 377 | TooManyLuidsRequested = 0xc0000074, 378 | LuidsExhausted = 0xc0000075, 379 | InvalidSubAuthority = 0xc0000076, 380 | InvalidAcl = 0xc0000077, 381 | InvalidSid = 0xc0000078, 382 | InvalidSecurityDescr = 0xc0000079, 383 | ProcedureNotFound = 0xc000007a, 384 | InvalidImageFormat = 0xc000007b, 385 | NoToken = 0xc000007c, 386 | BadInheritanceAcl = 0xc000007d, 387 | RangeNotLocked = 0xc000007e, 388 | DiskFull = 0xc000007f, 389 | ServerDisabled = 0xc0000080, 390 | ServerNotDisabled = 0xc0000081, 391 | TooManyGuidsRequested = 0xc0000082, 392 | GuidsExhausted = 0xc0000083, 393 | InvalidIdAuthority = 0xc0000084, 394 | AgentsExhausted = 0xc0000085, 395 | InvalidVolumeLabel = 0xc0000086, 396 | SectionNotExtended = 0xc0000087, 397 | NotMappedData = 0xc0000088, 398 | ResourceDataNotFound = 0xc0000089, 399 | ResourceTypeNotFound = 0xc000008a, 400 | ResourceNameNotFound = 0xc000008b, 401 | ArrayBoundsExceeded = 0xc000008c, 402 | FloatDenormalOperand = 0xc000008d, 403 | FloatDivideByZero = 0xc000008e, 404 | FloatInexactResult = 0xc000008f, 405 | FloatInvalidOperation = 0xc0000090, 406 | FloatOverflow = 0xc0000091, 407 | FloatStackCheck = 0xc0000092, 408 | FloatUnderflow = 0xc0000093, 409 | IntegerDivideByZero = 0xc0000094, 410 | IntegerOverflow = 0xc0000095, 411 | PrivilegedInstruction = 0xc0000096, 412 | TooManyPagingFiles = 0xc0000097, 413 | FileInvalid = 0xc0000098, 414 | InstanceNotAvailable = 0xc00000ab, 415 | PipeNotAvailable = 0xc00000ac, 416 | InvalidPipeState = 0xc00000ad, 417 | PipeBusy = 0xc00000ae, 418 | IllegalFunction = 0xc00000af, 419 | PipeDisconnected = 0xc00000b0, 420 | PipeClosing = 0xc00000b1, 421 | PipeConnected = 0xc00000b2, 422 | PipeListening = 0xc00000b3, 423 | InvalidReadMode = 0xc00000b4, 424 | IoTimeout = 0xc00000b5, 425 | FileForcedClosed = 0xc00000b6, 426 | ProfilingNotStarted = 0xc00000b7, 427 | ProfilingNotStopped = 0xc00000b8, 428 | NotSameDevice = 0xc00000d4, 429 | FileRenamed = 0xc00000d5, 430 | CantWait = 0xc00000d8, 431 | PipeEmpty = 0xc00000d9, 432 | CantTerminateSelf = 0xc00000db, 433 | InternalError = 0xc00000e5, 434 | InvalidParameter1 = 0xc00000ef, 435 | InvalidParameter2 = 0xc00000f0, 436 | InvalidParameter3 = 0xc00000f1, 437 | InvalidParameter4 = 0xc00000f2, 438 | InvalidParameter5 = 0xc00000f3, 439 | InvalidParameter6 = 0xc00000f4, 440 | InvalidParameter7 = 0xc00000f5, 441 | InvalidParameter8 = 0xc00000f6, 442 | InvalidParameter9 = 0xc00000f7, 443 | InvalidParameter10 = 0xc00000f8, 444 | InvalidParameter11 = 0xc00000f9, 445 | InvalidParameter12 = 0xc00000fa, 446 | MappedFileSizeZero = 0xc000011e, 447 | TooManyOpenedFiles = 0xc000011f, 448 | Cancelled = 0xc0000120, 449 | CannotDelete = 0xc0000121, 450 | InvalidComputerName = 0xc0000122, 451 | FileDeleted = 0xc0000123, 452 | SpecialAccount = 0xc0000124, 453 | SpecialGroup = 0xc0000125, 454 | SpecialUser = 0xc0000126, 455 | MembersPrimaryGroup = 0xc0000127, 456 | FileClosed = 0xc0000128, 457 | TooManyThreads = 0xc0000129, 458 | ThreadNotInProcess = 0xc000012a, 459 | TokenAlreadyInUse = 0xc000012b, 460 | PagefileQuotaExceeded = 0xc000012c, 461 | CommitmentLimit = 0xc000012d, 462 | InvalidImageLeFormat = 0xc000012e, 463 | InvalidImageNotMz = 0xc000012f, 464 | InvalidImageProtect = 0xc0000130, 465 | InvalidImageWin16 = 0xc0000131, 466 | LogonServer = 0xc0000132, 467 | DifferenceAtDc = 0xc0000133, 468 | SynchronizationRequired = 0xc0000134, 469 | DllNotFound = 0xc0000135, 470 | IoPrivilegeFailed = 0xc0000137, 471 | OrdinalNotFound = 0xc0000138, 472 | EntryPointNotFound = 0xc0000139, 473 | ControlCExit = 0xc000013a, 474 | PortNotSet = 0xc0000353, 475 | DebuggerInactive = 0xc0000354, 476 | CallbackBypass = 0xc0000503, 477 | PortClosed = 0xc0000700, 478 | MessageLost = 0xc0000701, 479 | InvalidMessage = 0xc0000702, 480 | RequestCanceled = 0xc0000703, 481 | RecursiveDispatch = 0xc0000704, 482 | LpcReceiveBufferExpected = 0xc0000705, 483 | LpcInvalidConnectionUsage = 0xc0000706, 484 | LpcRequestsNotAllowed = 0xc0000707, 485 | ResourceInUse = 0xc0000708, 486 | ProcessIsProtected = 0xc0000712, 487 | VolumeDirty = 0xc0000806, 488 | FileCheckedOut = 0xc0000901, 489 | CheckOutRequired = 0xc0000902, 490 | BadFileType = 0xc0000903, 491 | FileTooLarge = 0xc0000904, 492 | FormsAuthRequired = 0xc0000905, 493 | VirusInfected = 0xc0000906, 494 | VirusDeleted = 0xc0000907, 495 | TransactionalConflict = 0xc0190001, 496 | InvalidTransaction = 0xc0190002, 497 | TransactionNotActive = 0xc0190003, 498 | TmInitializationFailed = 0xc0190004, 499 | RmNotActive = 0xc0190005, 500 | RmMetadataCorrupt = 0xc0190006, 501 | TransactionNotJoined = 0xc0190007, 502 | DirectoryNotRm = 0xc0190008, 503 | CouldNotResizeLog = 0xc0190009, 504 | TransactionsUnsupportedRemote = 0xc019000a, 505 | LogResizeInvalidSize = 0xc019000b, 506 | RemoteFileVersionMismatch = 0xc019000c, 507 | CrmProtocolAlreadyExists = 0xc019000f, 508 | TransactionPropagationFailed = 0xc0190010, 509 | CrmProtocolNotFound = 0xc0190011, 510 | TransactionSuperiorExists = 0xc0190012, 511 | TransactionRequestNotValid = 0xc0190013, 512 | TransactionNotRequested = 0xc0190014, 513 | TransactionAlreadyAborted = 0xc0190015, 514 | TransactionAlreadyCommitted = 0xc0190016, 515 | TransactionInvalidMarshallBuffer = 0xc0190017, 516 | CurrentTransactionNotValid = 0xc0190018, 517 | LogGrowthFailed = 0xc0190019, 518 | ObjectNoLongerExists = 0xc0190021, 519 | StreamMiniversionNotFound = 0xc0190022, 520 | StreamMiniversionNotValid = 0xc0190023, 521 | MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024, 522 | CantOpenMiniversionWithModifyIntent = 0xc0190025, 523 | CantCreateMoreStreamMiniversions = 0xc0190026, 524 | HandleNoLongerValid = 0xc0190028, 525 | NoTxfMetadata = 0xc0190029, 526 | LogCorruptionDetected = 0xc0190030, 527 | CantRecoverWithHandleOpen = 0xc0190031, 528 | RmDisconnected = 0xc0190032, 529 | EnlistmentNotSuperior = 0xc0190033, 530 | RecoveryNotNeeded = 0xc0190034, 531 | RmAlreadyStarted = 0xc0190035, 532 | FileIdentityNotPersistent = 0xc0190036, 533 | CantBreakTransactionalDependency = 0xc0190037, 534 | CantCrossRmBoundary = 0xc0190038, 535 | TxfDirNotEmpty = 0xc0190039, 536 | IndoubtTransactionsExist = 0xc019003a, 537 | TmVolatile = 0xc019003b, 538 | RollbackTimerExpired = 0xc019003c, 539 | TxfAttributeCorrupt = 0xc019003d, 540 | EfsNotAllowedInTransaction = 0xc019003e, 541 | TransactionalOpenNotAllowed = 0xc019003f, 542 | TransactedMappingUnsupportedRemote = 0xc0190040, 543 | TxfMetadataAlreadyPresent = 0xc0190041, 544 | TransactionScopeCallbacksNotSet = 0xc0190042, 545 | TransactionRequiredPromotion = 0xc0190043, 546 | CannotExecuteFileInTransaction = 0xc0190044, 547 | TransactionsNotFrozen = 0xc0190045, 548 | 549 | MaximumNtStatus = 0xffffffff 550 | } 551 | [Flags] 552 | internal enum ProcessAccessFlags : UInt32 553 | { 554 | All = 0x001F0FFF, 555 | Terminate = 0x00000001, 556 | CreateThread = 0x00000002, 557 | VirtualMemoryOperation = 0x00000008, 558 | VirtualMemoryRead = 0x00000010, 559 | VirtualMemoryWrite = 0x00000020, 560 | DuplicateHandle = 0x00000040, 561 | CreateProcess = 0x000000080, 562 | SetQuota = 0x00000100, 563 | SetInformation = 0x00000200, 564 | QueryInformation = 0x00000400, 565 | QueryLimitedInformation = 0x00001000, 566 | Synchronize = 0x00100000 567 | } 568 | [Flags] 569 | internal enum DuplicateOptions : UInt32 570 | { 571 | None = 0, 572 | /// 573 | /// // Closes the source handle. This occurs regardless of any error status returned. 574 | /// 575 | DuplicateCloseSource = 0x00000001, 576 | /// 577 | /// //Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle. 578 | /// 579 | DuplicateSameAccess = 0x00000002 580 | } 581 | internal enum ObjectInfoamtionClass : Int32 582 | { 583 | ObjectBasicInformation = 0, 584 | ObjectNameInformation = 1, 585 | ObjectTypeInformation = 2, 586 | ObjectAllTypesInformation = 3, 587 | ObjectHandleInformation = 4 588 | } 589 | [StructLayout(LayoutKind.Sequential)] 590 | internal struct RmUniqueProcess 591 | { 592 | public Int32 ProcessId; 593 | public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime; 594 | } 595 | internal enum RmAppType 596 | { 597 | RmUnknownApp = 0, 598 | RmMainWindow = 1, 599 | RmOtherWindow = 2, 600 | RmService = 3, 601 | RmExplorer = 4, 602 | RmConsole = 5, 603 | RmCritical = 1000 604 | } 605 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 606 | internal struct RmProcessInfo 607 | { 608 | public RmUniqueProcess Process; 609 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] //CCH_RM_MAX_APP_NAME+1 610 | public String ApplicationName; 611 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] //CCH_RM_MAX_SVC_NAME+1 612 | public String ServiceShortName; 613 | public RmAppType ApplicationType; 614 | public RmAppStatus AppStatus; 615 | public Int32 TSSessionId; 616 | public Boolean bRestartable; 617 | public Int32 Size => Marshal.SizeOf(typeof(RmProcessInfo)); 618 | } 619 | [Flags] 620 | internal enum RmRebootReason 621 | { 622 | None = 0x0, 623 | PermissionDenied = 0x1, 624 | SessionMismatch = 0x2, 625 | CriticalProcess = 0x4, 626 | CriticalService = 0x8, 627 | DetectedSelf = 0x10 628 | } 629 | [Flags] 630 | internal enum RmAppStatus 631 | { 632 | RmStatusUnknown = 0x0, 633 | RmStatusRunning = 0x1, 634 | RmStatusStopped = 0x2, 635 | RmStatusStoppedOther = 0x4, 636 | RmStatusRestarted = 0x8, 637 | RmStatusErrorOnStop = 0x10, 638 | RmStatusErrorOnRestart = 0x20, 639 | RmStatusShutdownMasked = 0x40, 640 | RmStatusRestartMasked = 0x80 641 | } 642 | 643 | } 644 | 645 | 646 | 647 | 648 | --------------------------------------------------------------------------------