1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用AspNet Core或纯静态HTML文件的跨平台桌面应用程序

使用AspNet Core或纯静态HTML文件的跨平台桌面应用程序

时间:2018-07-02 00:06:17

相关推荐

使用AspNet Core或纯静态HTML文件的跨平台桌面应用程序

目录

介绍

背景

解决方案的说明

A C#类来控制Chrome浏览器

将Chrome与.Net Core控制台应用程序(静态Web应用程序)一起使用

将Chrome与AspNet Core MVC应用程序结合使用

Chrome类的Launch()方法

“普通” HTML演示应用程序

AspNet Core演示应用程序

发布AspNet Core演示应用程序

结论

下载最新的存储库存档

一种使用C#和Chrome开发跨平台桌面GUI应用程序的方法,它是Electron和库的非常轻巧的替代方案。

源代码可以在github上找到

介绍

该项目使用现有的Chrome安装程序将AspNet Core应用程序或由静态文件(html,javascript和css)组成的纯HTML应用程序呈现为桌面应用程序。

不需要Chromium或NodeJS,也不需要Chromium嵌入式框架(CEF)或CefSharp。

背景

这个想法很古老:为什么不使用html,javascript和css构建可被浏览器执行从而跨平台的桌面应用程序?

这个问题有很多答案。其中一些如下:

ChromelyOouiApache Cordova(mobile)Ionic(mobile)SpiderEyeSteve Sanderson's WebWindowWebViewWebView-csGoogle's CarloCarloSharpPositron

解决方案的说明

此解决方案基于以下想法:在运行MS Windows或Linux或MacOS的计算机中,有很大一部分安装了Google的Chrome浏览器。同时,.Net Core和AspNet Core在所有这些OS上运行。

所需要的是一种首先创建Chrome浏览器实例,然后指示其导航到“主页” URL的方法。

已经有一个使用NodeJS的方式做以上说的内容:是Mathias Bynens的优秀Puppeteer的NodeJS库。Google提供了一个有关Puppeteer的门户,其中包含许多有价值的信息和示例。

再有是Puppeteer的C#端口,Darío Kondratiuk的Puppeteer-Sharp。

这是来自github的Puppeteer的描述。

Puppeteer是一个Node库,它提供了高级API来通过DevTools协议控制Chrome或Chromium。Puppeteer默认情况下headless运行,但可以配置为运行完整(non-headless)的Chrome或Chromium。

此解决方案不是基于Headless Chrome浏览器的。相反,它使用的是普通的Chrome窗口,其中只有一个标签页,根本没有地址栏。Puppeteer,当然还有Puppeteer-Sharp都可以通过这种方式运行Chrome浏览器。

A C#类来控制Chrome浏览器

该项目包含一个名为Chrome的静态类,其中包含不到400行代码,该类用于启动Chrome并导航到第一个HTML页面。为此,Chrome类提供Launch()方法

static public void Launch(ChromeStartOptions Options, Action Closed = null)

当浏览器关闭时,它接受一个Options对象和一个回调来调用。这是ChromeStartOptions类。

public class ChromeStartOptions{public ChromeStartOptions(bool IsAspNetCoreApp = true){this.IsAspNetCoreApp = IsAspNetCoreApp;}public bool IsAspNetCoreApp { get; set; } = true;public string ChromePath { get; set; } = "";public string HomeUrl { get; set; } = @"Index.html";public string ContentFolder { get; set; } = "wwwroot";public int Left { get; set; } = 300;public int Top { get; set; } = 150;public int Width { get; set; } = 1024;public int Height { get; set; } = 768;}

HomeUrl和ContentFolder特性用于静态HTML应用程序,而不是ASPNET Core应用程序。

将Chrome与.Net Core控制台应用程序(静态Web应用程序)一起使用

这是在.Net Core控制台应用程序中使用它的方法,以便将纯HTML应用程序呈现为桌面应用程序。

static void Main(string[] args){ManualResetEvent CloseEvent = new ManualResetEvent(false); Chrome.Launch(new ChromeStartOptions(false), () => {CloseEvent.Set();}); CloseEvent.WaitOne();}

将Chrome与AspNet Core MVC应用程序结合使用

这里是如何从AspNet Core Startup类的Configure()方法内部调用它的方法,以便将AspNet Core MVC应用程序呈现为桌面应用程序。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){// code here ....// call Chrome as the last thing in the Configure methodChrome.Launch(new ChromeStartOptions(true), () => {IHostApplicationLifetime LifeTime = app.ApplicationServices.GetService(typeof(IHostApplicationLifetime)) as IHostApplicationLifetime;LifeTime.StopApplication();});}

Chrome类的Launch()方法

通过ChromeStartOptions实例传递给Launch()方法的标志指示应用程序的类型。True表示AspNet Core,而false表示纯静态HTML应用程序。

调用者可以通过ChromeStartOptions类的实例将更多信息传递给Launch()方法。ChromePath就是这样一点信息,表示可以找到Chrome的路径。

目前,该Crome类已尽力寻找在Windows和Linux上安装Chrome浏览器的位置。我计划研究Chrome启动器项目的代码,并尝试更好地解决此问题。

该Chrome.Launch()方法调用Chrome.LaunchAsync()执行以下操作的方法:

处理传入的选项准备一个Puppeteer-Sharp的LaunchOptions实例。调用Puppeteer.LaunchAsync(options)方法并返回一个Browser实例。如果这是AspNet Core应用程序,则该选项实例已准备好并且已经包含初始Url。否则,此步骤将推迟。现在Chrome已启动并运行,并显示一个标签Page。该代码获得对此Page的引用。如果这不是AspNet Core应用程序,请将事件处理程序链接到该Page以满足传如请求,因为没有web服务器。紧接着调用Page.GoToAsync(url)传递应用程序的“主页” URL。在下一步中,在两种情况下,都将另一个事件处理程序链接到Page,以处理浏览器的关闭。

这是Chrome.LaunchAsync()方法的完整代码。

static public async Task LaunchAsync(ChromeStartOptions Options, Action Closed = null){if (Browser == null){// prepare optionsIsAspNetCoreApp = Options.IsAspNetCoreApp;if (!string.IsNullOrWhiteSpace(Options.ContentFolder)){ContentFolder = Path.GetFullPath(Options.ContentFolder);} HomeUrl = !IsAspNetCoreApp ? $@"http://{SStaticApp}/{Options.HomeUrl}" : $"http://localhost:{Port}"; List<string> ArgList = new List<string>(DefaultArgs);string AppValue = !IsAspNetCoreApp ? "data:text/html, loading..." : Chrome.HomeUrl;ArgList.Add($"--app={AppValue}"); // The --app= argument opens Chrome in app mode that is no fullscreen, no url bar, just the windowArgList.Add($"--window-size={Options.Width},{Options.Height}");ArgList.Add($"--window-position={Options.Left},{Options.Top}");LaunchOptions LaunchOptions = new LaunchOptions{Devtools = false,Headless = false,Args = ArgList.ToArray(),ExecutablePath = !string.IsNullOrWhiteSpace(Options.ChromePath) ? Options.ChromePath : FindChromPath(),DefaultViewport = null};// launch ChromeBrowser = await Puppeteer.LaunchAsync(LaunchOptions);// get the main tab pagePage[] Pages = await Browser.PagesAsync().ConfigureAwait(false);TabPage = Pages[0];// event handler for static filesif (!IsAspNetCoreApp){await TabPage.SetRequestInterceptionAsync(true);TabPage.Request += StaticRequestHandler;await TabPage.GoToAsync(Chrome.HomeUrl, WaitUntilNavigation.DOMContentLoaded);}// event handler for closeTabPage.Close += (sender, ea) => {Closed?.Invoke();Closed = null;TabPage = null;if (!Browser.IsClosed)Browser.CloseAsync();Browser = null;};}}

“普通” HTML演示应用程序

简单的情况。这是一个.Net Core 3.0控制台应用程序。

输出类型设置为Windows应用程序只是为了在运行时隐藏控制台框。

该应用程序碰巧包含一个名为wwwroot的文件夹,这是该ChromeStartOptions类的ContentFolder属性的默认值。

public string ContentFolder { get; set; } = "wwwroot";

该ContentFolder属性指示放置静态文件(html,js,css)的根目录文件夹。

wwwroot文件夹中包含index.html,这又恰好是默认值文件ChromeStartOptions类中的HomeUrl属性的默认值。

public string HomeUrl { get; set; } = @"Index.html";

这是正在运行的应用程序。

AspNet Core演示应用程序

它是一个AspNet Core 3.0 MVC应用程序,没有比Visual Studio 预览版模板生成的代码更多的代码。

为了使该应用程序正常工作,需要做一些事情。

项目文件的第一个PropertyGroup应如下所示。

<PropertyGroup><TargetFramework>netcoreapp3.0</TargetFramework><AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel><ApplicationIcon /><OutputType>WinExe</OutputType><StartupObject /></PropertyGroup>

上面的代码使应用程序处于“进程外”状态,并在运行时隐藏了控制台。

随后是在Properties文件夹中找到的lauchSettings.json文件。

{"profiles": {"PuppetMvc": {"commandName": "Project","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"},"applicationUrl": "http://localhost:5000"}}}

这就是所有文件内容。只需一个配置文件,完全没有有关IIS Express的设置。该5000端口实际上未被应用程序使用。该Chrome类的发现和使用第一个自由端口。

Program类应该是如下这样。

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();} public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.ConfigureKestrel(o =>{o.Listen(IPAddress.Loopback, Chrome.Port); }).UseStartup<Startup>();});}

与模板代码的唯一区别在于,它配置了Kestrel以侦听所选端口。

这是正在运行的应用程序。

发布AspNet Core演示应用程序

这是发布设置。

在“修剪”所有未使用的程序集之后,以上内容在单个文件中创建了一个自包含部署。

这是发布文件夹的内容。* .exe大小为43 MB,包含所有内容,包括AspNet Core。只有静态文件位于wwwroot文件夹中。

最棒的是:双击* .exe在Chrome浏览器中运行该应用程序。

结论

多亏了Chrome和Puppeteer-Sharp,创建了使用Web技术构建的跨平台桌面应用程序的另一种可能性。这不需要Chromium或NodeJS或其他任何东西。它唯一需要知道的是Chrome的安装位置。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。