WPF中Windows.Services.Store订阅购买RequestPurchaseAsync调用失败问题
问题解决方案
核心错误原因
- 首次报错
Invalid window handle:未将商店操作关联到当前活动窗口的有效句柄,误用了未显示的空窗口句柄。 - 二次报错
Specified cast is not valid:错误地对StoreProduct调用InitializeWithWindow.Initialize,该方法的正确目标对象是StoreContext,而非产品实例。
具体修复步骤
1. 修正InitializeWithWindow的调用对象与窗口句柄
在PromptUserToPurchaseAsync方法中,替换错误的三行代码,改为初始化StoreContext并关联当前活动窗口的句柄:
' 替换原错误代码 Dim hwnd = New WindowInteropHelper(Me).Handle ' 获取当前按钮所在窗口的有效句柄 InitializeWithWindow.Initialize(context, hwnd) ' 初始化StoreContext而非StoreProduct
2. 修正订阅产品查询类型
在GetSubscriptionProductAsync方法中,查询订阅产品需使用"Subscription"类型标识符("Durable"对应永久附加组件,不匹配订阅):
Dim result As StoreProductQueryResult = Await context.GetAssociatedStoreProductsAsync(New String() {"Subscription"})
3. 添加窗口句柄有效性检查
避免传递无效句柄,可在初始化前增加判断:
Dim hwnd = New WindowInteropHelper(Me).Handle If hwnd = IntPtr.Zero Then MessageBox.Show("无法获取有效窗口句柄", "错误") Return End If InitializeWithWindow.Initialize(context, hwnd)
4. 确保InitializeWithWindow接口声明正确
若项目未自动生成相关接口,需手动添加COM接口声明:
Imports System.Runtime.InteropServices <ComImport> <Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")> <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> Public Interface IInitializeWithWindow Sub Initialize(ByVal hwnd As IntPtr) End Interface Public Class InitializeWithWindow Public Shared Sub Initialize(ByVal obj As Object, ByVal hwnd As IntPtr) DirectCast(obj, IInitializeWithWindow).Initialize(hwnd) End Sub End Class
完整修正后的PromptUserToPurchaseAsync方法
Private Async Function PromptUserToPurchaseAsync() As Task Try ' 获取当前窗口句柄并初始化StoreContext Dim hwnd = New WindowInteropHelper(Me).Handle If hwnd = IntPtr.Zero Then MessageBox.Show("无法获取有效窗口句柄", "错误") Return End If InitializeWithWindow.Initialize(context, hwnd) Dim result As StorePurchaseResult = Await subscriptionStoreProduct.RequestPurchaseAsync() Select Case result.Status Case StorePurchaseStatus.Succeeded MessageBox.Show("订阅购买成功。", "成功") AppGood = True Exit Function Case StorePurchaseStatus.NotPurchased MessageBox.Show("订阅购买未完成或已取消。", "失败") Exit Function Case StorePurchaseStatus.ServerError, StorePurchaseStatus.NetworkError MessageBox.Show("网络或服务器错误,请稍后重试。", "失败") Exit Function Case StorePurchaseStatus.AlreadyPurchased MessageBox.Show("订阅已激活,无需操作。", "成功") AppGood = True Exit Function End Select Catch ex As Exception MessageBox.Show(ex.Message, "RequestPurchaseAsync 错误") End Try End Function
额外注意事项
- 本地测试时,确保调用购买方法前当前窗口处于激活状态。
- 确认订阅SKU的StoreId与微软商店后台配置完全一致,避免匹配错误。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

