diff --git a/GetStoreApp/GetStoreApp.csproj b/GetStoreApp/GetStoreApp.csproj
index 2011c6254..6b6c17c06 100644
--- a/GetStoreApp/GetStoreApp.csproj
+++ b/GetStoreApp/GetStoreApp.csproj
@@ -121,7 +121,7 @@
-
+
diff --git a/GetStoreApp/GetStoreAppResource.res b/GetStoreApp/GetStoreAppResource.res
index 4e5f81c28..c071cd011 100644
Binary files a/GetStoreApp/GetStoreAppResource.res and b/GetStoreApp/GetStoreAppResource.res differ
diff --git a/GetStoreApp/Properties/AssemblyInfo.cs b/GetStoreApp/Properties/AssemblyInfo.cs
index 6b9a0d04f..577b60e8d 100644
--- a/GetStoreApp/Properties/AssemblyInfo.cs
+++ b/GetStoreApp/Properties/AssemblyInfo.cs
@@ -7,11 +7,11 @@
[assembly: AssemblyCompany("高怡飞")]
[assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")]
[assembly: AssemblyDescription("获取商店应用")]
-[assembly: AssemblyFileVersion("3.9.426.0")]
-[assembly: AssemblyInformationalVersion("3.9.426.0")]
+[assembly: AssemblyFileVersion("3.10.503.0")]
+[assembly: AssemblyInformationalVersion("3.10.503.0")]
[assembly: AssemblyProduct("获取商店应用")]
[assembly: AssemblyTitle("获取商店应用")]
-[assembly: AssemblyVersion("3.9.426.0")]
+[assembly: AssemblyVersion("3.10.503.0")]
// 设置程序集对 COM 组件的访问权限
[assembly: ComVisible(false)]
diff --git a/GetStoreApp/Services/Controls/Download/DeliveryOptimizationService.cs b/GetStoreApp/Services/Controls/Download/DeliveryOptimizationService.cs
index 084f5bf7b..abfe42279 100644
--- a/GetStoreApp/Services/Controls/Download/DeliveryOptimizationService.cs
+++ b/GetStoreApp/Services/Controls/Download/DeliveryOptimizationService.cs
@@ -3,8 +3,10 @@
using GetStoreApp.WindowsAPI.PInvoke.Ole32;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
+using System.Threading.Tasks;
using Windows.Foundation.Diagnostics;
namespace GetStoreApp.Services.Controls.Download
@@ -15,31 +17,77 @@ namespace GetStoreApp.Services.Controls.Download
public static class DeliveryOptimizationService
{
private static string displayName = "GetStoreApp";
+ private static object deliveryOptimizationLock = new object();
private static Guid CLSID_DeliveryOptimization = new Guid("5b99fa76-721c-423c-adac-56d03c8a8007");
private static Guid IID_DOManager = new Guid("400E2D4A-1431-4C1A-A748-39CA472CFDB1");
+ private static StrategyBasedComWrappers comWrappers = new StrategyBasedComWrappers();
private static Dictionary DeliveryOptimizationDict { get; } = new Dictionary();
+ public static event Action DownloadCreated;
+
+ public static event Action DownloadContinued;
+
+ public static event Action DownloadPaused;
+
+ public static event Action DownloadAborted;
+
+ public static event Action DownloadProgressing;
+
+ public static event Action DownloadCompleted;
+
+ ///
+ /// 获取下载任务的数量
+ ///
+ public static int GetDownloadCount()
+ {
+ lock (deliveryOptimizationLock)
+ {
+ return DeliveryOptimizationDict.Count;
+ }
+ }
+
+ ///
+ /// 终止所有下载任务,仅用于应用关闭时
+ ///
+ public static void TerminateDownload()
+ {
+ if (GetDownloadCount() > 0)
+ {
+ lock (deliveryOptimizationLock)
+ {
+ foreach (KeyValuePair deliveryOptimizationKeyValue in DeliveryOptimizationDict)
+ {
+ deliveryOptimizationKeyValue.Value.Abort();
+ }
+ }
+ }
+ }
+
///
/// 使用下载链接创建下载
///
- public static unsafe string CreateDownload(string url, string saveFilePath)
+ public static unsafe void CreateDownload(string url, string saveFilePath)
{
string downloadID = string.Empty;
+
try
{
IDOManager doManager = null;
+ IDODownload doDownload = null;
+
// 创建 IDoManager
- int createResult = Ole32Library.CoCreateInstance(ref CLSID_DeliveryOptimization, IntPtr.Zero, CLSCTX.CLSCTX_LOCAL_SERVER, ref IID_DOManager, out IntPtr doDownloadPointer);
+ int createResult = Ole32Library.CoCreateInstance(ref CLSID_DeliveryOptimization, IntPtr.Zero, CLSCTX.CLSCTX_LOCAL_SERVER, ref IID_DOManager, out IntPtr doManagerPointer);
+
if (createResult is 0)
{
- StrategyBasedComWrappers strategyBasedComWrappers = new StrategyBasedComWrappers();
- doManager = (IDOManager)strategyBasedComWrappers.GetOrCreateObjectForComInstance(doDownloadPointer, CreateObjectFlags.None);
+ doManager = (IDOManager)comWrappers.GetOrCreateObjectForComInstance(doManagerPointer, CreateObjectFlags.None);
// 创建下载
if (doManager is not null)
{
- doManager.CreateDownload(out IDODownload doDownload);
+ doManager.CreateDownload(out doDownload);
+ ComWrappers.TryGetComInstance(doDownload, out IntPtr doDownloadPointer);
int proxyResult = Ole32Library.CoSetProxyBlanket(doDownloadPointer, uint.MaxValue, uint.MaxValue, unchecked((IntPtr)ulong.MaxValue), 0, 3, IntPtr.Zero, 32);
// 添加下载信息
@@ -49,25 +97,29 @@ public static unsafe string CreateDownload(string url, string saveFilePath)
doDownload.SetProperty(DODownloadProperty.DODownloadProperty_Uri, &urlVarient);
ComVariant filePathVarient = ComVariant.Create(saveFilePath);
doDownload.SetProperty(DODownloadProperty.DODownloadProperty_LocalPath, &filePathVarient);
- ComVariant foregroundVarient = ComVariant.Create(true);
+
DODownloadStatusCallback doDownloadStatusCallback = new DODownloadStatusCallback();
doDownloadStatusCallback.StatusChanged += OnStatusChanged;
-
- // 正在学习 COM 源生成......
- ComVariant callbackInterfaceVarient = ComVariant.CreateRaw(VarEnum.VT_UNKNOWN, IntPtr.Zero);
+ IntPtr callbackPointer = comWrappers.GetOrCreateComInterfaceForObject(new UnknownWrapper(doDownloadStatusCallback).WrappedObject, CreateComInterfaceFlags.None);
+ ComVariant callbackInterfaceVarient = ComVariant.CreateRaw(VarEnum.VT_UNKNOWN, callbackPointer);
+ ComVariant foregroundVarient = ComVariant.Create(true);
doDownload.SetProperty(DODownloadProperty.DODownloadProperty_ForegroundPriority, &foregroundVarient);
- int startResult = doDownload.Start(IntPtr.Zero);
+ ComVariant idVarient = ComVariant.Null;
+ doDownload.GetProperty(DODownloadProperty.DODownloadProperty_Id, &idVarient);
+ ComVariant totalSizeVarient = ComVariant.Null;
+ doDownload.GetProperty(DODownloadProperty.DODownloadProperty_TotalSizeBytes, &totalSizeVarient);
+ downloadID = idVarient.As();
+ doDownloadStatusCallback.DownloadID = downloadID;
+ double size = Convert.ToDouble(totalSizeVarient.As());
+ DownloadCreated?.Invoke(downloadID, Path.GetFileName(saveFilePath), saveFilePath, url, Convert.ToDouble(totalSizeVarient.As()));
- // 下载启动成功,获取下载 Id,并添加到下载字典中
- if (startResult is 0)
+ lock (deliveryOptimizationLock)
{
- ComVariant idVarient = ComVariant.Null;
- doDownload.GetProperty(DODownloadProperty.DODownloadProperty_Id, &idVarient);
- downloadID = idVarient.As();
- doDownloadStatusCallback.DownloadID = downloadID;
DeliveryOptimizationDict.TryAdd(downloadID, doDownload);
}
+
+ int result = doDownload.Start(IntPtr.Zero);
}
}
}
@@ -75,67 +127,64 @@ public static unsafe string CreateDownload(string url, string saveFilePath)
{
LogService.WriteLog(LoggingLevel.Error, "Create delivery optimization download failed", e);
}
- return downloadID;
}
///
/// 删除下载
///
- public static bool DeleteDownload(string downloadID)
+ public static void DeleteDownload(string downloadID)
{
- try
+ Task.Run(() =>
{
- if (DeliveryOptimizationDict.TryGetValue(downloadID, out IDODownload doDownload))
+ try
{
- int abortResult = doDownload.Abort();
- return abortResult is 0;
+ if (DeliveryOptimizationDict.TryGetValue(downloadID, out IDODownload doDownload))
+ {
+ int abortResult = doDownload.Abort();
+ if (abortResult is 0)
+ {
+ DownloadAborted?.Invoke(downloadID);
+
+ DeliveryOptimizationDict.Remove(downloadID);
+ }
+ }
}
- else
+ catch (Exception e)
{
- return false;
+ LogService.WriteLog(LoggingLevel.Error, "Delete delivery optimization download failed", e);
}
- }
- catch (Exception e)
- {
- LogService.WriteLog(LoggingLevel.Error, "Delete delivery optimization download failed", e);
- return false;
- }
+ });
}
///
/// 下载状态发生变化触发的事件
///
- private static void OnStatusChanged(DODownloadStatusCallback callback, IDODownload download, DO_DOWNLOAD_STATUS status)
+ private static void OnStatusChanged(DODownloadStatusCallback callback, IDODownload doDownload, DO_DOWNLOAD_STATUS status)
{
- switch (status.State)
+ if (status.State is DODownloadState.DODownloadState_Transferring)
{
- case DODownloadState.DODownloadState_Created:
- {
- break;
- }
- case DODownloadState.DODownloadState_Transferring:
- {
- break;
- }
- case DODownloadState.DODownloadState_Transferred:
- {
- break;
- }
- case DODownloadState.DODownloadState_Aborted:
- {
- break;
- }
- case DODownloadState.DODownloadState_Finalized:
+ DownloadProgressing?.Invoke(callback.DownloadID, status);
+ }
+ else if (status.State is DODownloadState.DODownloadState_Transferred)
+ {
+ DownloadCompleted?.Invoke(callback.DownloadID, status);
+ try
+ {
+ callback.StatusChanged -= OnStatusChanged;
+ doDownload.Finalize();
+
+ lock (deliveryOptimizationLock)
{
- try
- {
- callback.StatusChanged -= OnStatusChanged;
- }
- catch (Exception)
+ if (DeliveryOptimizationDict.ContainsKey(callback.DownloadID))
{
+ DeliveryOptimizationDict.Remove(callback.DownloadID);
}
- break;
}
+ }
+ catch (Exception e)
+ {
+ LogService.WriteLog(LoggingLevel.Warning, "Finalize download task failed", e);
+ }
}
}
}
diff --git a/GetStoreApp/Views/Pages/StorePage.xaml.cs b/GetStoreApp/Views/Pages/StorePage.xaml.cs
index 97636309f..b7c9af51e 100644
--- a/GetStoreApp/Views/Pages/StorePage.xaml.cs
+++ b/GetStoreApp/Views/Pages/StorePage.xaml.cs
@@ -1,4 +1,5 @@
using GetStoreApp.Extensions.DataType.Enums;
+using GetStoreApp.Services.Controls.Download;
using GetStoreApp.Views.Windows;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
@@ -93,7 +94,8 @@ private void OnLoaded(object sender, RoutedEventArgs args)
///
private async void OnLanguageAndRegionClicked(object sender, RoutedEventArgs args)
{
- await Launcher.LaunchUriAsync(new Uri("ms-settings:regionformatting"));
+ //await Launcher.LaunchUriAsync(new Uri("ms-settings:regionformatting"));
+ DeliveryOptimizationService.CreateDownload("https://dldir1v6.qq.com/weixin/Windows/WeChatSetup.exe", @"C:\Users\Gaoyifei\Download\WeChatSetup.exe");
}
///
diff --git a/GetStoreApp/WindowsAPI/ComTypes/IDODownload.cs b/GetStoreApp/WindowsAPI/ComTypes/IDODownload.cs
index e334d4dee..557cbcfec 100644
--- a/GetStoreApp/WindowsAPI/ComTypes/IDODownload.cs
+++ b/GetStoreApp/WindowsAPI/ComTypes/IDODownload.cs
@@ -11,27 +11,35 @@ namespace GetStoreApp.WindowsAPI.ComTypes
public unsafe partial interface IDODownload
{
///
- /// 中止下载。
+ /// 启动或恢复下载,将可选范围作为指向 DO_DOWNLOAD_RANGES_INFO 结构的指针传递。
///
+ ///
+ /// 可选。 指向 DO_DOWNLOAD_RANGES_INFO 结构的指针 (仅下载文件) 的特定范围。 此处传递的值指示下载是针对整个文件或文件中的部分范围,还是只是为了在不更改范围信息的情况下继续下载。 通过传递指向空DO_DOWNLOAD_RANGES_INFO结构的指针来指示下载整个文件的请求,即,其 RangeCount 成员设置为零。 通过传递指向非空DO_DOWNLOAD_RANGES_INFO结构的指针来指示下载部分文件的请求。 nullptr仅当之前已使用空/非空范围开始下载一次时,才允许传递,并且指示必须恢复下载而不对请求的范围进行任何更改。
+ ///
/// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
[PreserveSig]
- int Abort();
+ int Start(IntPtr ranges);
///
- /// 完成下载。 完成后,无法通过调用 “开始”来恢复下载。
+ /// 暂停下载。
///
/// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
[PreserveSig]
- int Finalize();
+ int Pause();
///
- /// 检索指向包含特定下载属性的 VARIANT 的指针。
+ /// 中止下载。
///
- /// 获取 (DODownloadProperty) 类型所需的属性 ID。
- /// 生成的属性值,存储在 VARIANT 中。
/// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
[PreserveSig]
- int GetProperty(DODownloadProperty propId, ComVariant* propVal);
+ int Abort();
+
+ ///
+ /// 完成下载。 完成后,无法通过调用 “开始”来恢复下载。
+ ///
+ /// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
+ [PreserveSig]
+ int Finalize();
///
/// 指向 DO_DOWNLOAD_STATUS 结构的指针。
@@ -42,11 +50,13 @@ public unsafe partial interface IDODownload
int GetStatus(out DO_DOWNLOAD_STATUS status);
///
- /// 暂停下载。
+ /// 检索指向包含特定下载属性的 VARIANT 的指针。
///
+ /// 获取 (DODownloadProperty) 类型所需的属性 ID。
+ /// 生成的属性值,存储在 VARIANT 中。
/// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
[PreserveSig]
- int Pause();
+ int GetProperty(DODownloadProperty propId, ComVariant* propVal);
///
/// 检索指向包含特定下载属性的 VARIANT 的指针。
@@ -56,15 +66,5 @@ public unsafe partial interface IDODownload
/// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
[PreserveSig]
int SetProperty(DODownloadProperty propId, ComVariant* propVal);
-
- ///
- /// 启动或恢复下载,将可选范围作为指向 DO_DOWNLOAD_RANGES_INFO 结构的指针传递。
- ///
- ///
- /// 可选。 指向 DO_DOWNLOAD_RANGES_INFO 结构的指针 (仅下载文件) 的特定范围。 此处传递的值指示下载是针对整个文件或文件中的部分范围,还是只是为了在不更改范围信息的情况下继续下载。 通过传递指向空DO_DOWNLOAD_RANGES_INFO结构的指针来指示下载整个文件的请求,即,其 RangeCount 成员设置为零。 通过传递指向非空DO_DOWNLOAD_RANGES_INFO结构的指针来指示下载部分文件的请求。 nullptr仅当之前已使用空/非空范围开始下载一次时,才允许传递,并且指示必须恢复下载而不对请求的范围进行任何更改。
- ///
- /// 如果函数成功,则返回 S_OK。 否则,它将返回 HRESULT错误代码。
- [PreserveSig]
- int Start(IntPtr ranges);
}
}
diff --git a/GetStoreAppPackage/Package.appxmanifest b/GetStoreAppPackage/Package.appxmanifest
index 80a06f0cf..075b23c44 100644
--- a/GetStoreAppPackage/Package.appxmanifest
+++ b/GetStoreAppPackage/Package.appxmanifest
@@ -12,7 +12,7 @@
+ Version="3.10.503.0" />
ms-resource:PackageDisplayName
diff --git a/GetStoreAppWebView/GetStoreAppWebView.csproj b/GetStoreAppWebView/GetStoreAppWebView.csproj
index 00617da4e..b821a6d6a 100644
--- a/GetStoreAppWebView/GetStoreAppWebView.csproj
+++ b/GetStoreAppWebView/GetStoreAppWebView.csproj
@@ -62,7 +62,7 @@
-
+
diff --git a/GetStoreAppWebView/GetStoreAppWebViewResource.res b/GetStoreAppWebView/GetStoreAppWebViewResource.res
index bbe75a6fb..fa510ba50 100644
Binary files a/GetStoreAppWebView/GetStoreAppWebViewResource.res and b/GetStoreAppWebView/GetStoreAppWebViewResource.res differ
diff --git a/GetStoreAppWebView/Properties/AssemblyInfo.cs b/GetStoreAppWebView/Properties/AssemblyInfo.cs
index 08e3050d5..134747acd 100644
--- a/GetStoreAppWebView/Properties/AssemblyInfo.cs
+++ b/GetStoreAppWebView/Properties/AssemblyInfo.cs
@@ -7,11 +7,11 @@
[assembly: AssemblyCompany("高怡飞")]
[assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")]
[assembly: AssemblyDescription("网页浏览器")]
-[assembly: AssemblyFileVersion("3.9.426.0")]
-[assembly: AssemblyInformationalVersion("3.9.426.0")]
+[assembly: AssemblyFileVersion("3.10.503.0")]
+[assembly: AssemblyInformationalVersion("3.10.503.0")]
[assembly: AssemblyProduct("网页浏览器")]
[assembly: AssemblyTitle("网页浏览器")]
-[assembly: AssemblyVersion("3.9.426.0")]
+[assembly: AssemblyVersion("3.10.503.0")]
// 设置程序集对 COM 组件的访问权限
[assembly: ComVisible(false)]
diff --git a/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs b/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs
index 0f959cdb1..5450f926a 100644
--- a/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs
+++ b/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs
@@ -4,10 +4,10 @@
// 程序集信息设置
[assembly: AssemblyCompany("高怡飞")]
[assembly: AssemblyCopyright("©Copyright ©2022-2024 高怡飞, All Rights Reserved.")]
-[assembly: AssemblyFileVersion("3.9.426.0")]
-[assembly: AssemblyInformationalVersion("3.9.426.0")]
+[assembly: AssemblyFileVersion("3.10.503.0")]
+[assembly: AssemblyInformationalVersion("3.10.503.0")]
[assembly: AssemblyProduct("获取商店应用 WinGet WinRT 扩展")]
-[assembly: AssemblyVersion("3.9.426.0")]
+[assembly: AssemblyVersion("3.10.503.0")]
// 设置程序集仅允许在Windows平台上可用
[assembly: SupportedOSPlatform("windows10.0.22621")]