Skip to content

Commit

Permalink
Version 2019.4.19.1000, changes to handler processing, new icon & ass…
Browse files Browse the repository at this point in the history
…embly name
  • Loading branch information
thebookisclosed committed Apr 19, 2019
1 parent 2f24d6a commit 67af27a
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 55 deletions.
Binary file removed Comet/1.ico
Binary file not shown.
13 changes: 12 additions & 1 deletion Comet/Api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public static CleanupHandler InitializeHandler(string VolumeCacheName, string Ta
object evcInstance;
// This is needed due to Data Driven Cleaner {C0E13E61-0CC6-11d1-BBB6-0060978B2AE6} always throwing E_NOTIMPLEMENTED on <= Windows 7
try { evcInstance = Activator.CreateInstance(Type.GetTypeFromCLSID(evcProps.HandlerGuid)); }
catch {
catch
{
//System.Windows.Forms.MessageBox.Show(evcProps.HandlerGuid.ToString(), "Failed to load provider");
return null;
}
Expand Down Expand Up @@ -276,31 +277,41 @@ public interface IPropertyBag
[ClassInterface(ClassInterfaceType.None)]
public class EmptyVolumeCacheCallBacks : IEmptyVolumeCacheCallBack
{
// -2147467260 = 0x80004004 = E_ABORT
public int ScanProgress(long dwlSpaceUsed, uint dwFlags, IntPtr pcwszStatus)
{
if (Abort)
return -2147467260;
OnScanProgressChanged(new ScanProgressChangedEventArgs() { SpaceUsed = dwlSpaceUsed, Flags = (CallbackFlags)dwFlags });
return 0;
}

public int PurgeProgress(long dwlSpaceFreed, long dwlSpaceToFree, uint dwFlags, IntPtr pcwszStatus)
{
if (Abort)
return -2147467260;
OnPurgeProgressChanged(new PurgeProgressChangedEventArgs() { SpaceFreed = dwlSpaceFreed, SpaceToFree = dwlSpaceToFree, Flags = (CallbackFlags)dwFlags });
return 0;
}

public event EventHandler<ScanProgressChangedEventArgs> ScanProgressChanged;

[ComVisible(false)]
protected virtual void OnScanProgressChanged(ScanProgressChangedEventArgs e)
{
ScanProgressChanged?.Invoke(this, e);
}

public event EventHandler<PurgeProgressChangedEventArgs> PurgeProgressChanged;

[ComVisible(false)]
protected virtual void OnPurgeProgressChanged(PurgeProgressChangedEventArgs e)
{
PurgeProgressChanged?.Invoke(this, e);
}

[ComVisible(false)]
public bool Abort = false;
}

public class ScanProgressChangedEventArgs : EventArgs
Expand Down
7 changes: 4 additions & 3 deletions Comet/Comet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<ProjectGuid>{986C377A-A9CE-4FD1-BA44-280146F5BAF6}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Comet</RootNamespace>
<AssemblyName>Comet</AssemblyName>
<AssemblyName>mdiskclean</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
Expand Down Expand Up @@ -35,7 +35,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>1.ico</ApplicationIcon>
<ApplicationIcon>full.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
Expand Down Expand Up @@ -109,7 +109,8 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="1.ico" />
<Content Include="full.ico" />
<None Include="Resources\full.ico" />
<None Include="Resources\1.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down
4 changes: 2 additions & 2 deletions Comet/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2019.4.15.1004")]
[assembly: AssemblyFileVersion("2019.4.15.1004")]
[assembly: AssemblyVersion("2019.4.19.1000")]
[assembly: AssemblyFileVersion("2019.4.19.1000")]
4 changes: 2 additions & 2 deletions Comet/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Comet/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\1.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="full" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\full.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file removed Comet/Resources/1.ico
Binary file not shown.
Binary file added Comet/Resources/full.ico
Binary file not shown.
58 changes: 37 additions & 21 deletions Comet/UI/Cleaner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

Expand All @@ -13,20 +12,23 @@ public partial class Cleaner : Form
private Thread HandlerThread;
private long TotalBytesDeleted;
private int LastPercent;
private EmptyVolumeCacheCallBacks CallBacks;
private bool ProcessingHandlers;

public Cleaner()
{
InitializeComponent();
Icon = Properties.Resources._1;
Icon = Properties.Resources.full;
PtbLogo.Image = Icon.ToBitmap();
LblIntro.Text = string.Format(LblIntro.Text, Preferences.SelectedDrive.Name);
LblClnUp.Text += Preferences.SelectedDrive.Name;
LblHandler.Text = Preferences.CleanupHandlers[0].DisplayName;
HandlerThread = new Thread(new ThreadStart(() => {
Api.ReinstateHandlers(Preferences.CleanupHandlers, Preferences.SelectedDrive.Letter);
// Set up a callbacks for progress reporting
EmptyVolumeCacheCallBacks callBacks = new EmptyVolumeCacheCallBacks();
callBacks.PurgeProgressChanged += CallBacks_PurgeProgressChanged;
// Set up a callback for progress reporting
CallBacks = new EmptyVolumeCacheCallBacks();
CallBacks.PurgeProgressChanged += CallBacks_PurgeProgressChanged;
TotalBytesDeleted = 0;
ProcessingHandlers = true;
for (int i = 0; i < Preferences.CleanupHandlers.Count; i++)
{
CleanupHandler oHandler = Preferences.CleanupHandlers[i];
Expand All @@ -36,23 +38,25 @@ public Cleaner()
Invoke((MethodInvoker)delegate {
LblHandler.Text = oHandler.DisplayName;
});
try
int spaceResult = oHandler.Instance.GetSpaceUsed(out long newSpaceUsed, CallBacks);
if (spaceResult == -2147467260) // -2147467260 = 0x80004004 = E_ABORT
break;
else if (spaceResult == 0)
{
int purgeResult = oHandler.Instance.Purge(oHandler.BytesUsed, callBacks);
Preferences.CurrentSelectionSavings = Preferences.CurrentSelectionSavings - oHandler.BytesUsed + newSpaceUsed;
int purgeResult = oHandler.Instance.Purge(newSpaceUsed, CallBacks);
if (purgeResult == -2147467260) // -2147467260 = 0x80004004 = E_ABORT
break;
if (purgeResult != 0 && purgeResult != -2147287022) // -2147287022 == 0x80030012 == STG_E_NOMOREFILES
{
MessageBox.Show("Purging " + oHandler.DisplayName + " failed with error 0x" + purgeResult.ToString("x8"), Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (oHandler.PostProcHint != null)
RunProcHint(oHandler.PostProcHint);
try { oHandler.Instance.Deactivate(out uint dummy); } catch { }
Marshal.FinalReleaseComObject(oHandler.Instance);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), oHandler.DisplayName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try { oHandler.Instance.Deactivate(out uint dummy); } catch { }
Marshal.FinalReleaseComObject(oHandler.Instance);
}
ProcessingHandlers = false;
Api.DeactivateHandlers(Preferences.CleanupHandlers);
// A (stupid?) way to close the form once we are done cleaning
Invoke((MethodInvoker)delegate {
Close();
Expand All @@ -75,6 +79,10 @@ private void CallBacks_PurgeProgressChanged(object sender, PurgeProgressChangedE
if (e.Flags == CallbackFlags.LastNotification)
{
TotalBytesDeleted += e.SpaceToFree;
LastPercent = (int)((double)TotalBytesDeleted / Preferences.CurrentSelectionSavings * 100);
Invoke((MethodInvoker)delegate {
PrgClean.Value = LastPercent;
});
}
}

Expand Down Expand Up @@ -111,15 +119,23 @@ private void RunProcHint(string ProcHint)
p.StartInfo.FileName = fileName.Trim('"');
if (ProcHint.Length > fileName.Length + 1)
p.StartInfo.Arguments = ProcHint.Substring(fileName.Length + 1);
p.Start();
p.WaitForExit();
try
{
p.Start();
p.WaitForExit();
}
catch { MessageBox.Show("Couldn't start the following process: " + ProcHint, Text, MessageBoxButtons.OK, MessageBoxIcon.Error); }
}

private void BtnCancel_Click(object sender, EventArgs e)
{
HandlerThread.Abort();
Api.DeactivateHandlers(Preferences.CleanupHandlers);
Close();
if (HandlerThread.IsAlive && ProcessingHandlers)
CallBacks.Abort = true;
else
{
HandlerThread.Abort();
Close();
}
}
}
}
2 changes: 1 addition & 1 deletion Comet/UI/DriveSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public partial class DriveSelection : Form
public DriveSelection(List<DriveStrings> AvailableDrives)
{
InitializeComponent();
Icon = Properties.Resources._1;
Icon = Properties.Resources.full;
foreach (DriveStrings ds in AvailableDrives)
CbbDrives.Items.Add(ds);
CbbDrives.SelectedIndex = 0;
Expand Down
2 changes: 1 addition & 1 deletion Comet/UI/HandlerChoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public HandlerChoice()
{
InitializeComponent();
Text += Preferences.SelectedDrive.Name;
Icon = Properties.Resources._1;
Icon = Properties.Resources.full;
// Check if we are running as administrator, if yes, give the elevation button a shield
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
Expand Down
19 changes: 4 additions & 15 deletions Comet/UI/Scanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public partial class Scanner : Form
public Scanner()
{
InitializeComponent();
Icon = Properties.Resources._1;
Icon = Properties.Resources.full;
PtbLogo.Image = Icon.ToBitmap();
LblIntro.Text = string.Format(LblIntro.Text, Preferences.SelectedDrive.Name);
HandlerThread = new Thread(new ThreadStart(() => {
Expand All @@ -39,31 +39,20 @@ public Scanner()
LblHandler.Text = evp.DisplayName;
PrgScan.Value = i + 1;
});
long spaceUsed = 0;
try { evp.Instance.GetSpaceUsed(out spaceUsed, callBacks); }
catch
{
//MessageBox.Show(string.Format("Can't get used space for {0}, Flags {1}", evp.DisplayName, evp.Flags));
}
if (spaceUsed == 0 &&
int spaceResult = evp.Instance.GetSpaceUsed(out long spaceUsed, callBacks);
if (spaceResult != 0 || (spaceUsed == 0 &&
((evp.Flags & HandlerFlags.DontShowIfZero) == HandlerFlags.DontShowIfZero ||
(evp.DataDrivenFlags & DDCFlags.DontShowIfZero) == DDCFlags.DontShowIfZero))
(evp.DataDrivenFlags & DDCFlags.DontShowIfZero) == DDCFlags.DontShowIfZero)))
{
//MessageBox.Show(string.Format("Discarding {0} {1}", evp.DisplayName, evp.BytesUsed));
try { evp.Instance.Deactivate(out uint dummy); } catch { }
Marshal.FinalReleaseComObject(evp.Instance);
}
else
{
evp.BytesUsed = spaceUsed;
Preferences.CleanupHandlers.Add(evp);
//MessageBox.Show(string.Format("Adding {0} {1}", evp.DisplayName, evp.BytesUsed));
}
}
//else
//{
// MessageBox.Show(string.Format("{0} init ended with NULL", subKeyNames[i]));
//}
}
}
Api.DeactivateHandlers(Preferences.CleanupHandlers);
Expand Down
Binary file added Comet/full.ico
Binary file not shown.
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
# Managed Disk Cleanup (Comet)
Comet is a managed version of Disk Cleanup developed in C#.
Its purpose is to help out those who would like to automate specific cleanup related tasks.
It also serves as a peek into the world of backwards compatibility, given the fact that the Disk Cleanup API has barely changed since its introduction in 1997.
# Managed Disk Cleanup
![Logo](https://i.imgur.com/RFB7RjN.png)

Changes made to the Data Driven Cleaner object's functionality introduced in Windows 8 appear to be essential in order for the object to be activatable through a C# program. As a result, users running Windows 7 or older will be met with a message informing them of limited functionality at startup.
The goal of this project is to create an experience similar to the inbox Disk Cleanup program that ships with Windows. While regular users may simply opt to use this project as a free and open-source alternative, developers can make use of it to learn about the inner workings of the EmptyVolumeCache API that has been almost unchanged since its inception in 1997.

# Working with COM
This project is among the first few where I've worked with COM, thus some implementation may not be exactly ideal. Feedback is greatly appreciated.
One of the incentives for this project's development is the opened possibility for creating scripts or programs that clean up precisely what you want, instead of having to resort to using Disk Cleanup with command line arguments.

Some of the goals for future releases:

- Introduce Restore Point cleanup (Disk Cleanup offers this in its second tab in Administrator mode)
- Command line-only mode -- intended for better automation, with granular progress reporting
- An improved system for remembering which categories you've selected (currently mimics Disk Cleanup)
- Create a repository with a ready-made example for utilizing the API outside of a GUI

## Incompatibilities
Windows 8 introduced changes to the "Data Driven Cleaner" object that are essential for it to work under C#. This is a generic cleanup handler utilized by a handful of the offered cleanup categories. As a result, users using Windows 7 or an earlier OS will be met with a message informing them of limited functionality at startup.

## Reporting errors or bugs
If you happen to run into any of these, filing an issue here will be the most helpful. Besides describing the problem itself, please also include:
- Your system version (ideally the build number from winver)
- Your current system locale
- Whether you were running the program as Administrator

## Suggesting features / providing feedback
In case you'd like to share a suggestion, reaching out to me on [Twitter](https://twitter.com/thebookisclosed) would be the best.

0 comments on commit 67af27a

Please sign in to comment.