MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
444 stars 53 forks source link

electron.js-like app platform (feature request) #45

Closed pablocar80 closed 4 years ago

pablocar80 commented 5 years ago

One of the uses of WebView is to develop desktop applications using HTML5.

Could you extend WebView so that it can replace electron.js?

In other words -- could you make Edge and WebView work in .NET Core, across Windows/Linux/MacOS, and make it open inside its own window?

AB#28522681

david-risney commented 5 years ago

Interesting idea!

Could you extend WebView so that it can replace electron.js?

Electron has its own set of node APIs and access to node so it would be incredibly difficult to create a complete replacement for Electron. We might consider something in the future similar to Electron or similar to our previous JavaScript UWP app platform but probably not as a replacement. This feature isn't within the scope of what we're trying to do with WebView initially but something we can consider in the future.

In other words -- could you make Edge and WebView work in .NET Core, across Windows/Linux/MacOS, and make it open inside its own window?

We are planning .NET support (#23). Supporting other OSes might happen in the future but not in the near term.

Can you elaborate on what you would want to use it for? Did you have a specific use for this you'd like?

pablocar80 commented 5 years ago

I'm working on migrating a C# WinForms app to NET Core because I need to support MacOS and Linux. So I'm using .NET Core with ASP.NET Core.

But ASP.NET Core gets me only as far. It's a desktop application, not a website. So I need a simple form that can host the website locally, like electron does. Something that opens a form with a web browser inside. Today, this is simple to do if you develop for Windows only, as it's just a form with the web view control.

I don't need any of the node APIs that come with electron. It would be even desirable to get rid of that. The only part I need is opening a window with the browser inside, as simple as that, for Windows/Linux/MacOS.

david-risney commented 5 years ago

If you need an app window that hosts your website does building a PWA solve your needs?

pablocar80 commented 5 years ago

If I understood correctly PWA, the web application runs on a server (e.g. Azure) and is presented to the user as a desktop app. Electron runs everything on the client.

david-risney commented 5 years ago

Ah, my mistake I missed the part that your web content is local.

For the two parts of your feature request (1) simple JS app platform and (2) cross OS, they're both good suggestions but it will likely be a while before we can consider them (except for .NET support which we're working on currently)

verelpode commented 4 years ago

@pablocar80 -- it sounds like you want Microsoft Blazor including WebAssembly: https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor

pablocar80 commented 4 years ago

@verelpode not at all, that's still running inside a regular browser. Electron.js lets you open a form with the content and your own menu, getting rid of all the other elements of a browser -- the address bar, menus, options, navigation buttons, etc.

verelpode commented 4 years ago

@pablocar80 OK. WebView and WebView2 do get rid of all the other elements of a browser -- the address bar, menus, options, navigation buttons, etc. So maybe what you want is the combination of WebView2 plus Blazor/WebAssembly, but actually I don't fully understand your feature request.

pablocar80 commented 4 years ago

@verelpode It's already possible to develop desktop web apps without electron by using (A) WebView inside a thin container created with (B) WinForms and hosting a local site with (C) ASP.NET Core. However this works in Windows only.

Blazor has nothing to do with developing desktop web apps without electron. Blazor is framework to develop the web pages themselves, unrelated to the infrastructure needed to show web content on the client, which is what WebView does.

michael-hawker commented 4 years ago

🦙 There's also this project/discussion using the WebView2 preview as a base here: https://twitter.com/stevensanderson/status/1196448486033522688

GitHub repo: https://github.com/SteveSandersonMS/WebWindow

pablocar80 commented 4 years ago

@michael-hawker there's several repositories that attempt to solve the same problem as WebWindow, each with their own serious issues and at different stages of abandonment. Here's a few of them:

DeskGap Chromely WebView and its C# bindings WebView-CS CarloSharp NeutralinoJS

michael-hawker commented 4 years ago

@pablocar80 yup, I just wanted to point out the latest one that got started as it was built using WebView2. At least with the rich history here, it'd be nice to see that sort of scenario supported via the WebView itself somehow with this feature request.

mattkol commented 4 years ago

@pablocar80 any reason why the word "abandonment" is used for all repos? I am a maintainer on Chromely and it is not abandoned as far as I know.

pablocar80 commented 4 years ago

@pablocar80 any reason why the word "abandonment" is used for all repos? I am a maintainer on Chromely and it is not abandoned as far as I know.

At the time of writing Chromely was not yet a cross platform solution, I think mac was the one still missing. With “different stages” I meant a gradient from not abandoned to abandoned.

mattkol commented 4 years ago

At the time of writing Chromely was not yet a cross platform solution, I think mac was the one still missing. With “different stages” I meant a gradient from not abandoned to abandoned.

@pablocar80 sure that is ok, if a repo not offering solution on a platform means abandonment.

Some may not have been updated for more than 6 months (may be they qualify? I don't know what the standard is), but a couple of those were updated within a month. I still think unless a repo specifically says it is abandoned/archived, I do not think it is right to say it is. People put time and efforts into these projects and their efforts should be encouraged. Also developers who are looking for projects like these that may fit their needs may not be encouraged to visit the repos if they are learning about it from here.

May be I just read it wrongly/misunderstood.. but I know you mean well..

Thanks.

amaitland commented 3 years ago

For anyone interested in integrating Asp.Net Core directly into Chromium based browser then feel free to checkout Chromium.AspNetCore.Bridge.

Using OWIN and intercepting requests using WebResourceRequested the browser can make in-memory requests.

There's a WPF example that uses WebView2 with Asp.Net Core MVC

The relevant parts of the code are as below:

//https://github.com/amaitland/Chromium.AspNetCore.Bridge/blob/master/WebView2.AspNetCore.Mvc.Example.Wpf/App.xaml.cs
using Chromium.AspNetCore.Bridge;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Extensions.Logging;

namespace WebView2.AspNetCore.Mvc.Example.Wpf
{
    //Shorthand for Owin pipeline func
    using AppFunc = Func<IDictionary<string, object>, Task>;

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private IWebHost _host;
        private AppFunc _appFunc;

        public AppFunc AppFunc
        {
            get { return _appFunc; }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");

            _ = Task.Run(async () =>
              {
                  var builder = new WebHostBuilder();

                  builder.ConfigureServices(services =>
                  {
                      var server = new OwinServer();
                      server.UseOwin(appFunc =>
                      {
                          _appFunc = appFunc;
                      });

                      services.AddSingleton<IServer>(server);
                  });

                  builder.ConfigureLogging(logging =>
                  {
                      logging.AddConsole();
                  });

                  _host = builder
                      .UseStartup<Startup>()
                      .UseContentRoot(Directory.GetCurrentDirectory())
                      .Build();

                  await _host.RunAsync();
              });            
        }

        protected override void OnExit(ExitEventArgs e)
        {
            _host.StopAsync();

            base.OnExit(e);
        }
    }
}

// https://github.com/amaitland/Chromium.AspNetCore.Bridge/blob/master/WebView2.AspNetCore.Mvc.Example.Wpf/MainWindow.xaml.cs

using Microsoft.Web.WebView2.Core;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Chromium.AspNetCore.Bridge;

namespace WebView2.AspNetCore.Mvc.Example.Wpf
{
    //Shorthand for Owin pipeline func
    using AppFunc = Func<IDictionary<string, object>, Task>;

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private AppFunc _appFunc;

        public MainWindow()
        {
            InitializeComponent();

            Browser.CoreWebView2InitializationCompleted += Browser_CoreWebView2InitializationCompleted;
        }

        private void Browser_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            if (e.IsSuccess)
            {
                _appFunc = ((App)Application.Current).AppFunc;
                Browser.CoreWebView2.WebResourceRequested += BrowserWebResourceRequestedAsync;
                Browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
            }
        }

        private async void BrowserWebResourceRequestedAsync(object sender, CoreWebView2WebResourceRequestedEventArgs e)
        {
            var deferral = e.GetDeferral();

            var request = new ResourceRequest(e.Request.Uri, e.Request.Method, e.Request.Headers, e.Request.Content);

            var response = await RequestInterceptor.ProcessRequest(_appFunc, request);

            var coreWebView2 = (CoreWebView2)sender;

            e.Response = coreWebView2.Environment.CreateWebResourceResponse(response.Stream, response.StatusCode, response.ReasonPhrase, response.GetHeaderString());

            deferral.Complete();
        }
    }
}

Primarily I wrote this for use with CefSharp, I have since expanded the implement to be more generic and there are examples for CefSharp, Chromely, and WebView2 (It would be fairly trivial to integrate into CefGlue as well.

mattkol commented 3 years ago

Also for anyone interested, EdgeSharp using WebView2 also uses Chromium.AspNetCore.Bridge.