Skip to content

Commit aad9874

Browse files
committed
Use invoke method (GetDiskFreeSpaceEx) for getting disk space info (#72)
1 parent e7e5115 commit aad9874

14 files changed

+433
-62
lines changed

Binaries/Steam Library Manager.exe

10 KB
Binary file not shown.

Source/Steam Library Manager/Definitions/Global.cs

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
23
namespace Steam_Library_Manager.Definitions
34
{
45
internal static class Global
@@ -16,5 +17,11 @@ public static class Origin
1617
public static string ConfigFilePath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "Origin", "local.xml");
1718
public static List<KeyValuePair<string, string>> AppIds = new List<KeyValuePair<string, string>>();
1819
}
20+
21+
public static class Uplay
22+
{
23+
// AppData\Local\Ubisoft Game Launcher\settings.yml
24+
public static string ConfigFilePath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Ubisoft Game Launcher", "settings.yml");
25+
}
1926
}
2027
}

Source/Steam Library Manager/Definitions/Library.cs

+18-4
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,28 @@ public abstract class Library : INotifyPropertyChanged
1515
public bool IsMain { get; set; }
1616
public bool IsUpdatingAppList { get; set; }
1717
public DirectoryInfo DirectoryInfo { get; set; }
18-
public string FullPath { get; set; }
18+
private string _fullPath;
19+
20+
public string FullPath
21+
{
22+
get => _fullPath;
23+
set
24+
{
25+
_fullPath = value;
26+
Functions.FileSystem.DriveUsageStatistics(_fullPath, out var freeSpace, out var totalSpace, out var totalFreeSpace);
27+
28+
FreeSpace = (long)freeSpace;
29+
TotalSize = (long)totalSpace;
30+
}
31+
}
32+
1933
public System.Collections.ObjectModel.ObservableCollection<dynamic> Apps { get; set; } = new System.Collections.ObjectModel.ObservableCollection<dynamic>();
2034
public Dictionary<string, DirectoryInfo> DirectoryList { get; set; } = new Dictionary<string, DirectoryInfo>();
2135

22-
public long FreeSpace => DirectoryInfo.Exists && !DirectoryInfo.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()) ? Functions.FileSystem.GetAvailableFreeSpace(DirectoryInfo.FullName) : 0;
23-
public long TotalSize => DirectoryInfo.Exists && !DirectoryInfo.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()) ? Functions.FileSystem.GetAvailableTotalSpace(DirectoryInfo.FullName) : 0;
36+
public long FreeSpace { get; set; }
37+
public long TotalSize { get; set; }
2438
public string PrettyFreeSpace => DirectoryInfo.Exists && !DirectoryInfo.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()) ? $"{Functions.FileSystem.FormatBytes(FreeSpace)} / {Functions.FileSystem.FormatBytes(TotalSize)}" : "";
25-
public int FreeSpacePerc => DirectoryInfo.Exists && !DirectoryInfo.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()) ? 100 - ((int)Math.Round((double)(100 * FreeSpace) / Functions.FileSystem.GetAvailableTotalSpace(DirectoryInfo.FullName))) : 0;
39+
public int FreeSpacePerc => DirectoryInfo.Exists && !DirectoryInfo.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()) ? 100 - ((int)Math.Round((double)(100 * FreeSpace) / TotalSize)) : 0;
2640

2741
public List<FrameworkElement> ContextMenu => _contextMenuElements ?? (_contextMenuElements = GenerateCMenuItems());
2842
private List<FrameworkElement> _contextMenuElements;

Source/Steam Library Manager/Definitions/OriginLibrary.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public OriginLibrary(string fullPath, bool isMain = false)
1616
{
1717
FullPath = fullPath;
1818
IsMain = isMain;
19+
Type = Enums.LibraryType.Origin;
20+
DirectoryInfo = new DirectoryInfo(fullPath);
1921
}
2022

2123
public override async void UpdateAppListAsync()
@@ -33,9 +35,9 @@ public override async void UpdateAppListAsync()
3335

3436
await Directory.EnumerateFiles(FullPath, "installerdata.xml", SearchOption.AllDirectories)
3537
.ParallelForEachAsync(
36-
async originApp =>
38+
async filePath =>
3739
{
38-
await Functions.Origin.ParseAppDetailsAsync(new StreamReader(originApp).BaseStream, originApp, this);
40+
await Functions.Origin.ParseAppDetailsAsync(new StreamReader(filePath).BaseStream, filePath, this);
3941
});
4042

4143
await Directory.EnumerateFiles(FullPath, "*.zip", SearchOption.TopDirectoryOnly).ParallelForEachAsync(async originCompressedArchive =>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace Steam_Library_Manager.Definitions
8+
{
9+
public class UplayAppInfo : App
10+
{
11+
public UplayAppInfo(Library library, string appName, int appId, DirectoryInfo installationDirectory, bool isCompressed)
12+
{
13+
Library = library;
14+
AppName = appName;
15+
AppId = appId;
16+
InstallationDirectory = installationDirectory;
17+
IsCompressed = isCompressed;
18+
19+
LastUpdated = InstallationDirectory.LastWriteTimeUtc;
20+
CompressedArchivePath = new FileInfo(Path.Combine(Library.FullPath, AppId + ".zip"));
21+
SizeOnDisk = (!IsCompressed) ? Functions.FileSystem.GetDirectorySize(InstallationDirectory, true) : CompressedArchivePath.Length;
22+
IsCompacted = CompactStatus().Result;
23+
}
24+
25+
public override async void ParseMenuItemActionAsync(string action)
26+
{
27+
try
28+
{
29+
switch (action.ToLowerInvariant())
30+
{
31+
case "disk":
32+
InstallationDirectory.Refresh();
33+
34+
if (InstallationDirectory.Exists)
35+
{
36+
Process.Start(InstallationDirectory.FullName);
37+
}
38+
39+
break;
40+
41+
case "compress":
42+
if (Functions.TaskManager.TaskList.Count(x => x.App == this && x.TargetLibrary == Library && x.TaskType == Enums.TaskType.Compress) == 0)
43+
{
44+
Functions.TaskManager.AddTask(new List.TaskInfo
45+
{
46+
App = this,
47+
TargetLibrary = Library,
48+
TaskType = Enums.TaskType.Compress,
49+
Compress = !IsCompressed
50+
});
51+
}
52+
break;
53+
54+
case "compact":
55+
if (Functions.TaskManager.TaskList.Count(x => x.App == this && x.TargetLibrary == Library && x.TaskType == Enums.TaskType.Compact) == 0)
56+
{
57+
Functions.TaskManager.AddTask(new List.TaskInfo
58+
{
59+
App = this,
60+
TargetLibrary = Library,
61+
TaskType = Enums.TaskType.Compact
62+
});
63+
}
64+
break;
65+
66+
case "deleteappfiles":
67+
await Task.Run(async () => await DeleteFilesAsync()).ConfigureAwait(false);
68+
69+
Library.Apps.Remove(this);
70+
if (SLM.CurrentSelectedLibrary == Library)
71+
Functions.App.UpdateAppPanel(Library);
72+
73+
break;
74+
75+
case "deleteappfilestm":
76+
Functions.TaskManager.AddTask(new List.TaskInfo
77+
{
78+
App = this,
79+
TargetLibrary = Library,
80+
TaskType = Enums.TaskType.Delete
81+
});
82+
break;
83+
}
84+
}
85+
catch (Exception ex)
86+
{
87+
Logger.Error(ex);
88+
}
89+
}
90+
}
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Collections.Async;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.IO.Compression;
6+
using System.Linq;
7+
using System.Windows;
8+
9+
namespace Steam_Library_Manager.Definitions
10+
{
11+
public class UplayLibrary : Library
12+
{
13+
public UplayLibrary(string fullPath, bool isMain = false)
14+
{
15+
FullPath = fullPath;
16+
IsMain = isMain;
17+
Type = Enums.LibraryType.Uplay;
18+
DirectoryInfo = new DirectoryInfo(fullPath);
19+
}
20+
21+
public override async void UpdateAppListAsync()
22+
{
23+
try
24+
{
25+
if (IsUpdatingAppList)
26+
return;
27+
28+
IsUpdatingAppList = true;
29+
30+
Apps.Clear();
31+
32+
if (!Directory.Exists(FullPath)) return;
33+
34+
await Directory.EnumerateFiles(FullPath, "uplay_install.state", SearchOption.AllDirectories)
35+
.ParallelForEachAsync(
36+
async filePath =>
37+
{
38+
await Functions.Uplay.ParseAppDetailsAsync(new StreamReader(filePath).BaseStream, filePath, this);
39+
});
40+
41+
await Directory.EnumerateFiles(FullPath, "*.zip", SearchOption.TopDirectoryOnly).ParallelForEachAsync(async originCompressedArchive =>
42+
{
43+
using (var archive = ZipFile.OpenRead(originCompressedArchive))
44+
{
45+
if (archive.Entries.Count > 0)
46+
{
47+
foreach (var archiveEntry in archive.Entries.Where(x => x.Name.Contains("uplay_install.state")))
48+
{
49+
await Functions.Uplay.ParseAppDetailsAsync(archiveEntry.Open(), originCompressedArchive, this, true);
50+
}
51+
}
52+
}
53+
});
54+
55+
if (SLM.CurrentSelectedLibrary != null && SLM.CurrentSelectedLibrary == this)
56+
{
57+
Functions.App.UpdateAppPanel(this);
58+
}
59+
60+
IsUpdatingAppList = false;
61+
}
62+
catch (Exception ex)
63+
{
64+
MessageBox.Show($"An error happened while updating game list for Uplay library: {FullPath}\n{ex}");
65+
Logger.Fatal(ex);
66+
}
67+
}
68+
69+
public override void ParseMenuItemActionAsync(string action)
70+
{
71+
switch (action.ToLowerInvariant())
72+
{
73+
case "disk":
74+
if (Directory.Exists(FullPath))
75+
{
76+
Process.Start(FullPath);
77+
}
78+
break;
79+
80+
case "remove":
81+
RemoveLibraryAsync(false);
82+
break;
83+
}
84+
}
85+
86+
public override void RemoveLibraryAsync(bool withFiles)
87+
{
88+
if (withFiles)
89+
{
90+
throw new NotImplementedException();
91+
}
92+
else
93+
{
94+
List.Libraries.Remove(this);
95+
}
96+
}
97+
98+
public override void UpdateJunks()
99+
{
100+
throw new NotImplementedException();
101+
}
102+
}
103+
}

Source/Steam Library Manager/Forms/Main.xaml.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ public void UpdateLibraryList(object targetLibraryType)
187187
}
188188
}
189189

190-
private void MainForm_Loaded(object sender, RoutedEventArgs e)
190+
private async void MainForm_Loaded(object sender, RoutedEventArgs e)
191191
{
192-
_ = Functions.SLM.OnLoadAsync();
192+
await Functions.SLM.OnLoadAsync();
193193

194194
SettingsView.GeneralSettingsGroupBox.DataContext = new Definitions.Settings();
195195
QuickSettings.DataContext = SettingsView.GeneralSettingsGroupBox.DataContext;

Source/Steam Library Manager/Functions/FileSystem.cs

+12-31
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Runtime.InteropServices;
56
using System.Threading.Tasks;
67

78
namespace Steam_Library_Manager.Functions
@@ -161,42 +162,22 @@ public static string FormatBytes(long length)
161162
}
162163
}
163164

164-
public static long GetAvailableFreeSpace(string TargetFolder)
165-
{
166-
try
167-
{
168-
return new DriveInfo(Path.GetPathRoot(TargetFolder))?.AvailableFreeSpace ?? 0;
169-
}
170-
catch (ArgumentException ae)
171-
{
172-
logger.Fatal(ae);
165+
// Pinvoke for API function
166+
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
167+
[return: MarshalAs(UnmanagedType.Bool)]
168+
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
169+
out ulong lpFreeBytesAvailable,
170+
out ulong lpTotalNumberOfBytes,
171+
out ulong lpTotalNumberOfFreeBytes);
173172

174-
return 0;
175-
}
176-
catch (Exception ex)
177-
{
178-
logger.Fatal(ex);
179-
return 0;
180-
}
181-
}
182-
183-
public static long GetAvailableTotalSpace(string TargetFolder)
173+
public static bool DriveUsageStatistics(string folderName, out ulong availableFreeSpace, out ulong totalSpace, out ulong totalFreeSpace)
184174
{
185-
try
175+
if (!folderName.EndsWith("\\"))
186176
{
187-
return new DriveInfo(Path.GetPathRoot(TargetFolder))?.TotalSize ?? 0;
177+
folderName += '\\';
188178
}
189-
catch (ArgumentException ae)
190-
{
191-
logger.Fatal(ae);
192179

193-
return 0;
194-
}
195-
catch (Exception ex)
196-
{
197-
logger.Fatal(ex);
198-
return 0;
199-
}
180+
return GetDiskFreeSpaceEx(folderName, out availableFreeSpace, out totalSpace, out totalFreeSpace);
200181
}
201182
}
202183
}

0 commit comments

Comments
 (0)