简体   繁体   中英

How do you call a method from a UI thread?

I am trying to access the Microsoft Store from a multi-threaded program. The program itself work well - no problems there, but the method

Windows.Foundation.IAsyncOperation<StorePurchaseResult> purchase = product.RequestPurchaseAsync();

throws the exception:

"Invalid window handle.\r\n\r\nThis function must be called from a UI thread"

My code is as follows...

        private void testButton_Click(object sender, EventArgs e)
        {
            //Dispatcher dispUI = Dispatcher.CurrentDispatcher;
            //dispUI.BeginInvoke((ThreadStart)delegate ()
            //{
            //    _ = SetStore();
            //});

            //Dispatcher.BeginInvoke(new Action(TestStuff));


            _ = SetStore();

        }

        [ComImport]
        [Guid("4AEEEC08-7C92-4456-A0D6-1B675C7AC005")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IInitializeWithWindow
        {
            void Initialize(IntPtr hwnd);
        }


        private async Task SetStore()
        {
            try
            {
                StoreContext theStore = StoreContext.GetDefault();

                // "Unable to cast object of type 'Windows.Services.Store.StoreContext' to type 'IInitializeWithWindow'."
                // IInitializeWithWindow initWindow = (IInitializeWithWindow)(object)theStore;
                // initWindow.Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);

                StoreProductResult app = await theStore.GetStoreProductForCurrentAppAsync();

                // This works...
                StoreProduct product = app.Product;
                string title = product.Title;
                string price = product.Price.FormattedPrice;

                // This works...
                StoreAppLicense license = await theStore.GetAppLicenseAsync();
                bool trial = license.IsTrial;
                bool full = license.IsActive;

                // "Invalid window handle.\r\n\r\nThis function must be called from a UI thread" 
                StorePurchaseResult result = await theStore.RequestPurchaseAsync("9NRFBVGVGW8K");


                // "Invalid window handle.\r\n\r\nThis function must be called from a UI thread" 
                // Windows.Foundation.IAsyncOperation<StorePurchaseResult> purchase = product.RequestPurchaseAsync();
            }
            catch (Exception e)
            {
                int a = 1;
            }

        }

I have associated the VS2019 UWP installer project with the store, which I figure is why the other methods return the right answers without needing to cast the store object with IInitializeWithWindow (which also throws an error, but which bypassing seems to let the code work).

I figure I have to tap into the UI thread somehow - go no idea how. Various examples from all over the place don't seem to work for me. Can anyone help me?

EDIT: This is a.Net program with a UWP wrapper creating a MSIX package.

For UWP, you need to use the following bit of code to call to the UI thread:

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
    //UI code here
});

Try following, It works for me for .net 6 wpf app

WinRT.Interop.InitializeWithWindow.Initialize(storeContext, new WindowInteropHelper(window).Handle);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM