Target is .NET 7.0. Target OS: 10.0.22621.0 Min Supported OS: 10.0.17763
App was certified in the windows store before adding the subscription code. On Save, it checks subscription status.
We followed https://learn.microsoft.com/en-us/windows/uwp/monetize/enable-subscription-add-ons-for-your-app converted to VB.
MS Store reports that the code gets available subscription and works until subscriptionStoreProduct.RequestPurchaseAsync. Here it failed saying "Invalid window handle. (0x80070578) Consider WIndowNative, InitializeWithWindow". We added code for InitialzeWithWindow and now it fails saying "Specified cast is not valid". Extra code is enclosed by ''''' comments
There doesn't appear to be a sandbox for troubleshooting this so we have to keep resubmitting the app for certification and waiting for it to fail.
How do we fix this? Code posted below:
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
You cannot get a valid window handle from WindowInteropHelper.Handle until the Window is initialized. Use existing opened Window, if any, to get a window handle for IInitializeWithWindow.Initialize method.
Or you can use WindowInteropHelper.EnsureHandle method to make the Window to create its window handle and retrieve it.
Dim mywin = New Window
Dim hwnd = New WindowInteropHelper(mywin).EnsureHandle