Windows.Services.Store WPF 在 subscriptionStoreProduct.RequestPurchaseAsync 失败

Windows.Services.Store WPF fails at subscriptionStoreProduct.RequestPurchaseAsync

提问人:Jamie 提问时间:6/16/2023 最后编辑:emoachtJamie 更新时间:6/18/2023 访问量:60

问:

目标是 .NET 7.0。 目标操作系统:10.0.22621.0 最低支持的操作系统:10.0.17763

在添加订阅代码之前,应用已在 Windows 应用商店中认证。在“保存”中,它会检查订阅状态。

我们随后 https://learn.microsoft.com/en-us/windows/uwp/monetize/enable-subscription-add-ons-for-your-app 转换为 VB。

MS Store 报告代码获得可用订阅,并在 subscriptionStoreProduct.RequestPurchaseAsync 之前一直有效。在这里它失败了,说“无效的窗口句柄。(0x80070578) 考虑 WIndowNative, InitializeWithWindow”。我们为 InitialzeWithWindow 添加了代码,现在它失败,提示“指定的强制转换无效”。额外的代码被 ''' 注释括起来

似乎没有用于解决此问题的沙盒,因此我们必须不断重新提交应用程序进行认证并等待其失败。

我们如何解决这个问题?代码发布在下面:

Private context As StoreContext
Private subscriptionStoreId As String = "************"
Private subscriptionStoreProduct As StoreProduct

Public Async Function SetupSubscriptionInfoAsync() As Task
    Try
        context = StoreContext.GetDefault()
        Dim userOwnsSubscription As Boolean = Await CheckIfUserHasSubscriptionAsync()
        If userOwnsSubscription Then
            AppGood = True
            Exit Function
        End If
        subscriptionStoreProduct = Await GetSubscriptionProductAsync()
        Dim sku As StoreSku = subscriptionStoreProduct.Skus(0)
        If sku.SubscriptionInfo.HasTrialPeriod Then
            MessageBox.Show("7 day trial available", "Trial")
        Else
            MessageBox.Show(sku.SubscriptionInfo.BillingPeriod & " (Subscription Period)" & vbCrLf & sku.SubscriptionInfo.BillingPeriodUnit & " (Subscription Period Unit)", "Subscription")
        End If
        Await PromptUserToPurchaseAsync()
    Catch ex As Exception
        MessageBox.Show("Error accessing Windows Store for subscription status.", "SetupSubscriptionInfoAsync Error")
    End Try
End Function

Private Async Function CheckIfUserHasSubscriptionAsync() As Task(Of Boolean)
    Try
        Dim appLicense As StoreAppLicense = Await context.GetAppLicenseAsync()
        For Each addOnLicense In appLicense.AddOnLicenses
            Dim license As StoreLicense = addOnLicense.Value
            If license.SkuStoreId.StartsWith(subscriptionStoreId) Then
                If license.IsActive Then
                    Return True
                    Exit Function
                End If
            End If
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message, "CheckIfUserHasSubscriptionAsync Error")
    End Try
    Return False
End Function

Private Async Function GetSubscriptionProductAsync() As Task(Of StoreProduct)
    Try
        Dim result As StoreProductQueryResult = Await context.GetAssociatedStoreProductsAsync(New String() {"Durable"})
        For Each item In result.Products
            Dim product As StoreProduct = item.Value
            If product.StoreId = subscriptionStoreId Then
                Return product
                Exit Function
            End If
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message, "GetSubscriptionProductAsync Error")
        Return Nothing
    End Try
    Return Nothing
End Function

Private Async Function PromptUserToPurchaseAsync() As Task
    Try
'''''these 3 lines were added after inital error
        Dim mywin = New Window
        Dim hwnd = New WindowInteropHelper(mywin).Handle
        InitializeWithWindow.Initialize(subscriptionStoreProduct, hwnd)
'''''

        Dim result As StorePurchaseResult

        result = Await subscriptionStoreProduct.RequestPurchaseAsync()

        Select Case result.Status
            Case StorePurchaseStatus.Succeeded
                MessageBox.Show("Subscription purchase successful.", "Success")
                AppGood = True
                Exit Function
            Case StorePurchaseStatus.NotPurchased
                MessageBox.Show("Subscription purchase did not complete or was cancelled.", "Fail")
                Exit Function
            Case StorePurchaseStatus.ServerError, StorePurchaseStatus.NetworkError
                MessageBox.Show("Network or server error, please try again later.", "Fail")
                Exit Function
            Case StorePurchaseStatus.AlreadyPurchased
                MessageBox.Show("Subscription already active, no action necessary.", "Success")
                AppGood = True
                Exit Function
        End Select
    Catch ex As Exception
        MessageBox.Show(ex.Message, "RequestPurchaseAsync Error")
    End Try
End Function

Private Async Sub btnSave_Click(sender As Object, e As RoutedEventArgs) Handles btnSave.Click
    Await SetupSubscriptionInfoAsync()
    If AppGood Then
        Dim MainWin As New MainWindow
        MainWin.Show()
        Me.Close()
    Else
        MessageBox.Show("No valid license.", "No license")
    End If
End Sub
WPF vb.net 订阅 Windows-Store

评论

0赞 emoacht 6/17/2023
你的意图是什么?通常,您不需要在此处创建新窗口。Dim mywin = New Window
0赞 Jamie 6/18/2023
同意,但是对于原始错误,即我们应该使用 InitializeWithWindow,我们添加了它,以便我们可以获取句柄并将其与 InitializeWithWindow 一起使用。我们做错了吗?

答:

0赞 emoacht 6/18/2023 #1

在初始化 Window 之前,无法从 WindowInteropHelper.Handle 获取有效的窗口句柄。使用现有打开的 Window(如果有)获取 IInitializeWithWindow.Initialize 方法的窗口句柄。

或者,可以使用 WindowInteropHelper.EnsureHandle 方法使 Window 创建其窗口句柄并检索它。

Dim mywin = New Window
Dim hwnd = New WindowInteropHelper(mywin).EnsureHandle

评论

0赞 Jamie 6/21/2023
知道了,没有打开的窗口,因为尝试打开 Windows 应用商店时发生错误,因此我们将使用 EnsureHandle 并重新提交它进行认证。谢谢!
0赞 Jamie 7/4/2023
失败,但已引起我们的注意,Initializewithwindow 应该在 StoreContext 上使用,而不是 StoreProduct,所以我们现在正在尝试。
0赞 Jamie 7/5/2023
认证并工作,感谢您的帮助!