2022年11月2日水曜日

WIN32ストアサブスクリプションコード

 C#でSTOREのサブスクリプションコードを書きました。サブスクリプションコードは、アプリ内にあります。一方サブスクリプションは、アドオンによる実装なので、どんな風にサブスクリプションのダイアログが表示されるのかストアに公開しないと分かりません。また、動くかどうか分からないないので、とりあえず、デバッグ用のユーザグループをPrivateで作成、公開してデバッグしようという戦略です。ユーザは、一度でも購入すると後戻り出来ないので、複数のPrivateユーザを設定しています。(0円設定なのでデバッグでお金はかかりません。従いα、β..とアプリの名前を変えつつRefineしていくしか方法がないように思います。Sandboxとかないようです。)

<C#からWindows RTを呼び出すコードのエラー>

Win32アプリであるC#からの呼び出し部でコンパイルエラーが生じました。


Error CS4036 'IAsyncOperation' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'IAsyncOperation' could be found (are you missing a using directive for 'System'?)


<対処方法>
https://stackoverflow.com/questions/61263356/how-do-i-get-an-app-licence-from-microsoft-store
https://stackoverflow.com/questions/44099401/frombluetoothaddressasync-iasyncoperation-does-not-contain-a-definition-for-get/44102996#44102996

nuget UwpDesktop-Updatedでインストール 症状同じ
nuget System.Runtime.WindowsRuntimeでインストール エラー解消




#if STORE
using Windows.Services.Store;

#endif

#if STORE
        async Task AsyncMethod()
        {

            await SetupSubscriptionInfoAsync();


        }
        private StoreContext context = null;
        private StoreProduct subscriptionStoreProduct;
        private bool has_lincese = false;
        public async Task SetupSubscriptionInfoAsync()
        {
            if (context == null)
            {
                context = StoreContext.GetDefault();
                // If your app is a desktop app that uses the Desktop Bridge, you
                // may need additional code to configure the StoreContext object.
                // For more info, see https://aka.ms/storecontext-for-desktop.
            }
            

            bool userOwnsSubscription = await CheckIfUserHasSubscriptionAsync();
            if (userOwnsSubscription)
            {

                // Unlock all the subscription add-on features here.
                has_lincese = true;
                return;
            }
            StoreProductQueryResult result= await GetSubscriptionsInfo();
            if (result == null)//subscriptionそのものがない
            {
                has_lincese = true;
                return;
            }
            // Prompt the customer to purchase the subscription.
            await PromptUserToPurchaseAsync();

          

        }

        private async Task CheckIfUserHasSubscriptionAsync()
        {
            StoreAppLicense appLicense = await context.GetAppLicenseAsync();

            // Check if the customer has the rights to the subscription.
            foreach (var addOnLicense in appLicense.AddOnLicenses)
            {
                StoreLicense license = addOnLicense.Value;
     
                {
                    if (license.IsActive)
                    {
                        DateTimeOffset now = DateTimeOffset.Now;
                        TimeSpan TS = now - license.ExpirationDate;
                        TimeSpan TSR = new TimeSpan(25, 0, 0, 0);//25days hours min sec
                        if (TS <=TSR)//25日以下になったら表示
                        {
                            string stm = rm.GetString("expiration_date") +  license.ExpirationDate.ToString();
                            MessageBox.Show(stm);
                        }
                        // The expiration date is available in the license.ExpirationDate property.
                        return true;
                    }
                }
            }

            // The customer does not have a license to the subscription.
            return false;
        }

        
        private async Task PromptUserToPurchaseAsync()
        {
            // Request a purchase of the subscription product. If a trial is available it will be offered 
            // to the customer. Otherwise, the non-trial SKU will be offered.
            StorePurchaseResult result = await subscriptionStoreProduct.RequestPurchaseAsync();

            // Capture the error message for the operation, if any.
            string extendedError = string.Empty;
            if (result.ExtendedError != null)
            {
                extendedError = result.ExtendedError.Message;
            }
            string stm = extendedError+" ";
            switch (result.Status)
            {
                case StorePurchaseStatus.Succeeded:
                    // Show a UI to acknowledge that the customer has purchased your subscription 
                    // and unlock the features of the subscription. 
                    has_lincese = true;
                    stm += rm.GetString("thank_you");

                    break;

                case StorePurchaseStatus.NotPurchased:
                    has_lincese = false;
                    stm += rm.GetString("see_you_again");
                    System.Diagnostics.Debug.WriteLine("The purchase did not complete. " +
                        "The customer may have cancelled the purchase. ExtendedError: " + extendedError);
                    break;

                case StorePurchaseStatus.ServerError:
                case StorePurchaseStatus.NetworkError:
                    has_lincese = false;
                    stm += rm.GetString("server_error");
                    System.Diagnostics.Debug.WriteLine("The purchase was unsuccessful due to a server or network error. " +
                        "ExtendedError: " + extendedError);
                    break;

                case StorePurchaseStatus.AlreadyPurchased:
                    has_lincese = true;
                    stm += rm.GetString("already_puchased");
                    System.Diagnostics.Debug.WriteLine("The customer already owns this subscription." +
                            "ExtendedError: " + extendedError);
                    break;
            }
            MessageBox.Show(stm);

        }
        public string get_date_info(StoreDurationUnit u, uint billingPeriod)
        {
            string s = "";
            s += billingPeriod.ToString();
            switch (u)
            {
                case (StoreDurationUnit.Minute): s += rm.GetString("Minute");break;
                case (StoreDurationUnit.Hour): s += rm.GetString("Hour");break;
                case (StoreDurationUnit.Day): s += rm.GetString("Day");break;
                case (StoreDurationUnit.Week): s += rm.GetString("Weeks");break;
                case (StoreDurationUnit.Month): s += rm.GetString("Month");break;
                case (StoreDurationUnit.Year): s += rm.GetString("Year");break;
                
            }
            return s;
        }
        public async Task GetSubscriptionsInfo()
        {
            if (context == null)
            {
                context = StoreContext.GetDefault();
                // If your app is a desktop app that uses the Desktop Bridge, you
                // may need additional code to configure the StoreContext object.
                // For more info, see https://aka.ms/storecontext-for-desktop.
            }

            // Subscription add-ons are Durable products.
            string[] productKinds = { "Durable" };
            List filterList = new List(productKinds);

            StoreProductQueryResult queryResult =
                await context.GetAssociatedStoreProductsAsync(productKinds);

            if (queryResult.ExtendedError != null)
            {
                // The user may be offline or there might be some other server failure.
                System.Diagnostics.Debug.WriteLine($"ExtendedError: {queryResult.ExtendedError.Message}");
                return null;
            }
            string stm = "";
            foreach (KeyValuePair item in queryResult.Products)
            {
                // Access the Store product info for the add-on.
               
                
                StoreProduct product = item.Value;
                subscriptionStoreProduct = product;//productを保存する。

                string store_id = product.StoreId;
                string store_title = product.Title;
                string store_price = product.Price.FormattedPrice;

                stm += store_id +" ";
                stm += store_title + " ";
                stm += store_price + " ";
                // For each add-on, the subscription info is available in the SKU objects in the add-on. 
                foreach (StoreSku sku in product.Skus)
                {
                    if (sku.IsSubscription)
                    {
                        // Use the sku.SubscriptionInfo property to get info about the subscription. 
                        // For example, the following code gets the units and duration of the 
                        // subscription billing period.
                        StoreDurationUnit billingPeriodUnit = sku.SubscriptionInfo.BillingPeriodUnit;

                        uint billingPeriod = sku.SubscriptionInfo.BillingPeriod;
                        stm += rm.GetString("subscription") + " ";
                        stm +=get_date_info(billingPeriodUnit,billingPeriod );
                    }
                    else if (sku.IsTrial)
                    {
                        stm += rm.GetString("trial");
                        
                    }
                }
                stm += "\n";
            }
            MessageBox.Show(stm);
            return queryResult;
        }
#endif

0 件のコメント:

コメントを投稿