0

I have a simple desktop application which loads .cshtml view in a windows form. I build it and published on my remote machine for a specific folder on drive D. Everything works fine, if only 1 user from this machine runs the instance of this application on a target path. But if any other user try to run the same app, while the copy of that app is already running by another user it sees a blank form instead.

I've already covered the code with some logging and try{} catch{} blocks, but have no interesting info so far. The service which returns the desktop view runs at the same intranet and it returns the result all the time if you just go to URL against the browser.

What could be the problem and how can I find the true cause of its appearance?

I will be grateful for any advice.

Update 1: CoreWebView2InitializationCompleted contains an exception -> The requested resource is in use. (0x800700AA)

     #region Windows Form Designer generated code

        /// <summary>
        ///  Required method for Designer support - do not modify
        ///  the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.webView = new Microsoft.Web.WebView2.WinForms.WebView2();
            ((System.ComponentModel.ISupportInitialize)(this.webView)).BeginInit();
            this.SuspendLayout();
            // 
            // webView
            // 
            this.webView.AllowExternalDrop = false;
            this.webView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.webView.CreationProperties = null;
            this.webView.DefaultBackgroundColor = System.Drawing.Color.White;
            this.webView.Location = new System.Drawing.Point(10, 10);
            this.webView.Name = "webView";
            this.webView.Size = new System.Drawing.Size(690, 125);
            this.webView.TabIndex = 0;
            this.webView.ZoomFactor = 1D;
            // 
            // MainForm
            // 
            this.AccessibleDescription = "MessageBoard Wrapper";
            this.AccessibleName = "MessageBoard Wrapper";
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(710, 145);
            this.Controls.Add(this.webView);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MinimumSize = new System.Drawing.Size(250, 100);
            this.Name = "MainForm";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "MessageBoard Wrapper";
            ((System.ComponentModel.ISupportInitialize)(this.webView)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

       private HttpClient GetClient()
       {
         var result = new HttpClient();
         return result;
       }

        private Microsoft.Web.WebView2.WinForms.WebView2 webView;

        private string _baseUrl = "here I have my service url";

    public MainForm()
        {
            
            InitializeComponent();
            FormBorderStyle = FormBorderStyle.None;
            DoubleBuffered = true;
            SetStyle(ControlStyles.ResizeRedraw, true);
            var client = GetClient();
                try
                {
                    var targetmUrlForCustomBusinessLogic = "url address here";
                    var response = client.GetAsync(targetmUrlForCustomBusinessLogic).Result;

                    if (response.IsSuccessStatusCode)
                    {
                        var t = Task.Run(() => response.Content.ReadAsStringAsync()).Result;

                     //here I have some code too

                    }

                }
                catch (Exception ex)
                {
                    var message = ex.Message;
                    //TODO: add logging here
                  
                }
                finally
                {
                    client.Dispose();
                }

            webView.Source = new Uri(_baseUrl);

            webView.NavigationCompleted += WebView_NavigationCompleted;

            ResizeEnd += (object sender, EventArgs e) => SaveFormSettings();
            Move += (object sender, EventArgs e) => SaveFormSettings();
            Shown += (object sender, EventArgs e) => LoadFormSettings();
        }

enter image description here

Eugene D
  • 347
  • 1
  • 3
  • 17
  • .Net Core 3.1 ?! Move to .Net 6 -- You're not initializing the WebView2 Control – Jimi Nov 09 '22 at 13:35
  • We will move to .Net 6 definitely. The component initialization is going inside of InitializeComponent() method. As I told at the description all works well, if 1 copy of the app running at the same time. @Jimi – Eugene D Nov 09 '22 at 13:58
  • You cannot initialize a WebView2 control in `InitializeComponent()`, it uses async methods tat you need to await. Whatever you're doing, in relation to this Control, you have to show it here – Jimi Nov 09 '22 at 14:01
  • I've updated the post to provide more details, including the autogenerated code for InitializeComponent() method. @Jimi – Eugene D Nov 09 '22 at 14:17
  • 1
    You're setting up some base properties in `InitializeComponent()`, I'm referring to the async method that calls `await CoreWebView2Environment.CreateAsync(...)` and `await [WebView2 Instance].EnsureCoreWebView2Async(...)` etc. (i.e., the initialization procedure) – Jimi Nov 09 '22 at 14:27
  • 1
    The following may be helpful: https://stackoverflow.com/a/73846538/10024425, https://stackoverflow.com/a/71216493/10024425, and https://stackoverflow.com/a/66501901/10024425. – Tu deschizi eu inchid Nov 09 '22 at 15:00
  • I don't use either CoreWebView2Environment.CreateAsync() or EnsureCoreWebView2Async() in the app. Sorry, I'm a web developer, don't have much experience with desktop apps. @Jimi. – Eugene D Nov 09 '22 at 15:21
  • The following may also be helpful: [Manage user data folders](https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/user-data-folder?tabs=dotnet) – Tu deschizi eu inchid Nov 09 '22 at 15:32

1 Answers1

1

I got this application to work in multi user mode by making the following changes.

  1. I removed initialization of webView.Source property

  2. I added a method which is preparing the environment for each user and explicitly trigger the initialization of webView control. (I'm calling this method inside of MainForm

    private async Task InitAsync(string path) { var env = await Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(userDataFolder: path); await webView.EnsureCoreWebView2Async(env); }

  3. I set up path param for the user data folder in a next way

path = Path.Combine(Path.GetTempPath(), $"{Environment.UserName}");

  1. I binded navigation path to the target URL in against CoreWebView2InitializationCompleted event handler.

    private void webView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e) { if (webView != null && webView.CoreWebView2 != null) { webView.CoreWebView2.Navigate(_baseUrl); } }

All the steps above solved my issus, which was occuring because each new instance of the app for a new user requred environment folder to deal with webView component. Hope that will save some time for somebody.

Eugene D
  • 347
  • 1
  • 3
  • 17