准备工作

         本文面向所有Windows .NET程序员,需要具备以下几个方面的基础知识以及准备工作

  1. 修改.NET工程的编译选项,我们只支持64位应用(DebugRelease 64位编译);
  2. 下载 (点击)WebRuntime运行时支撑包,需要将运行时必要的支撑包放在与exe文件相同文件夹之内;
  3. 正确配置工程的Manifest文件(app.manifest包含在WebRuntime运行时支撑包之中);
  4. 正确引用Cosmos.dllCosmos.dll包含在WebRuntime运行时支撑包之中)
  5. 最好具备开发简单的Web页面能力;
  6. 您需要准备好一个(或者创建一个新的)C# WinForm工程;

具体的细节工作参考我们提供的 一分钟视频教程 操作。

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发

                           让.NET工程拥有互联网基因

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

Application.RunUniverse.Cosmos.Run

         您需要做的工作就是将

            Application.Run(new Form1());
一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

替换为

            Universe.Cosmos.Run();
一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

注意,在这里我们忽略了“new Form1()”。

沧桑巨变从此拉开帷幕

         修改一行代码之后,即可以重新编译您的工程。编译之后,我们枚举出几个基本的变化:

  1. 您的应用系统已经是一个基于.NET Framework的软件生态支撑环境;
  2. 您的应用系统已经是一个基于主流Web技术的软件生态支撑环境;
  3. 您的应用系统事实上已经是一个.NET、Java、Web综合生态环境;
  4. 您的应用系统类似Office VBA一样,拥有一个全方位的基于WinForm的Form集成机制,我们用.NET WinForm替代了 VBA的Form2,同时用Javascript替代了VBA宏语言,这一点意味着,您可以在Web页面之中,实例化.NET WinForm窗体、操作WinForm、User Control的事件,甚至创建您自己定义的DOM元素……;
  5. 您的应用系统事实上已经是一款Chromium为基础的现代Web Browser,与标准浏览器的差异是:我们允许第一个窗口是用户开发的自定义窗口,同时我们允许开发者在Web页面之中创建不同类型的Win32窗体,也就是说用户启动程序的时候,会首先显示一个开发者指定的窗口做为应用程序的主窗口,当用户启动应用程序的第二个实例,或者在程序中打开一个新的URL,会激活新的浏览器窗口,内置的全功能浏览器窗口支持面向应用的Web页面,除标准Web页面之外,支持扩展的DOM,WinForm、Usercontrol等等都是DOM元素,我们很快看到,新型页面是由标准Web页面与Windows GUI对象合成的;
  6. 您的应用系统事实上是由面向应用的Web页面支撑的“互联网内容”引擎;
  7. 您的应用系统可以在不同场景之下拥有不同的主窗口,我们提供基于目录结构的应用配置能力,也就是说,您可以将您的应用部署在不同的文件夹,每一个具体部署拥有完全不同的Web模型、本地应用模型,甚至不同的团队维护;
  8. 您的应用系统是一个由您、其他开发者或者开发团队以及大量的组件资源形成的综合软件生态圈。

应用从第一个Web页面开始

         我们注意到,Universe.Cosmos.Run()是无参数的,所以,应用系统启动的时候不会创建任何GUI对象。后续为了行文方便,我们假设已经有了一个符合我们条件的FirstApp.exe,这里FirstApp您大可以替换成您自己选择的任何C# WinForm工程。我们希望FirstApp里面的Form1是如下方式设计的:

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_05

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

(Form1上包含一个panel1,当然可以替换为其他控件……)

我们需要一个Web页面“FirstApp.index,html”,页面的具体代码如下:

<!-- This is "index.html". Normally, it is named "ProjectName.index.html". This webpage is the real entry point of the HTML-driven App. -->
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>欢迎您进入一个全新的.NET世界, 我是您的朋友WebRuntime</title>
    <link rel="icon" href="webpage/app.png" sizes="32x32">
</head>
<body>
    <cosmos>
        <!-- Define new DOM elements -->
        <define tagName="mainWindow"></define>
        <define tagName="application"></define>
        <define tagName="webViewport"></define>
        <!-- End Define new DOM elements -->
        <!-- The "application" element is required, it can provide application-level configuration. -->
        <application>
            <ntp>
                <winNucleus>
                    <xobj id='grid' rows='1' cols='2' width='350,350,' splitterwidth='6'>
                        <xobj objid="FirstApp.Form1,host"></xobj>
                        <xobj objid="nucleus"></xobj>
                    </xobj>
                </winNucleus>
            </ntp>
            <defaultworkbench>
                <winNucleus>
                    <xobj id='grid' rows='1' cols='2' width='350,350,' splitterwidth='6'>
                        <xobj objid="FirstApp.Form1,host"></xobj>
                        <xobj objid="nucleus"></xobj>
                    </xobj>
                </winNucleus>
            </defaultworkbench>
            <urls>
                <url url="host:WebPage/sunny.html"></url>
            </urls>
        </application>
        <mainWindow objid="FirstApp.Form1,host" caption="The Universe" width="2400" height="1600" id="mainForm">
            <panel1 id="mainworkclient">
                <default>
                    <winNucleus>
                        <xobj style="39" activepage="1">
                            <xobj caption="Cloudx Application" id='Splitter1' rows='1' cols='2' height='250,' width='350,350,' borderwidth='0' splitterwidth='6'>
                                <xobj objid="nucleus">
                                </xobj>
                                <xobj objid="" id="Sunny_ntpctrl">
                                </xobj>
                            </xobj>
                            <xobj caption="Common Web Runtime for Application" url="host"></xobj>
                        </xobj>
                    </winNucleus>
                </default>
            </panel1>
        </mainWindow>
        <webViewport>
            <winNucleus>
                <xobj rows="1" cols="2" width="750," id="xxx" caption="test caption">
                    <xobj objid="FirstApp.Form1,host" id="navCtrl">
                    </xobj>
                    <xobj objid="nucleus" id="mainClient">
                    </xobj>
                </xobj>
            </winNucleus>
        </webViewport>
    </cosmos>
    <strong style="font-size:32px; color:black">欢迎<i style="color:fuchsia">您来到</i><i style="color:blue">FirstApp的 </i><b style="color:coral">.NET桌面软件生态世界</b>!</strong>
</body>
</html>
一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

将这个页面复制到FirstApp.exe所在文件夹,注意,您需要下载WebRuntime运行时二进制包,并且将这个支持包放在可执行文件所在的文件夹。准备工作完毕之后,启动FirstApp.exe,以下是运行时视频:

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_08

           (FirstApp运行时视频)

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

我们看到如下一些画面:
 

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_10

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

(Form的中心区域呈现出非常明显的变化,设计时只有panel1,对比之下差异明显)

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_12

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

(Form窗体之上出现了标签化浏览器结构,就是说浏览器这里是子窗口,是Form的一部分)

点击页面上超链接,自然增加标签:

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_14

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

(动态多标签)

点击页面按钮:

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_16

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

(我们看到了新的Web页面结构,是由Form1与标准页面合成的)

当我们点击“Cloud Application”标签的时候,浏览器子窗口不见了,我们看到的是一个“1行2列”的Grid结构。

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_18

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

事实上,当我们回到FirstApp.Index.html,我们发现,所有的变化,都源于Web页面上的DOM元素。在FirstApp.index.html之中,我们看到如下内容:

            <winNucleus>
                <xobj rows="1" cols="2" width="750," id="xxx" caption="test caption">
                    <xobj objid="FirstApp.Form1,host" id="navCtrl">
                    </xobj>
                    <xobj objid="nucleus" id="mainClient">
                    </xobj>
                </xobj>
            </winNucleus>
一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

这里,”obj“,导致FirstApp内部的Form1成为运行时Form1的”一部分“,如下图:

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_互联网桌面应用开发_10

一行代码触发沧桑巨变: 从Application.Run()到Universe.Cosmos.Run_.NET桌面开发技术_02

我们似乎看到一种可能性:按照类似的写法,似乎所有的.NET UserControl都应该成为中心部分可以通过Web页面动态的加载上去,事实上,系统内部就是这样实现的。

        第一个Web页面表达了这样的设想:一旦Exe做为入口确定下来,那么那些符合规范的.NET GUI对象,都应该是Web页面驱动的元素,如果一个应用系统内置了浏览器,那么就意味着,开发者可以通过大量的写Web页面,营造出表现力极为丰富的”应用内容“空间,特别,这些Web页面可以成为一个Form窗体(更一般的情况:Win32窗体)的一部分,进而形成了一种通用集成的态势,原则上,符合.NET开发规范的那些控件,几乎都可以按照如上的页面结构,成为你GUI对象的一部分,我们后续会逐步展开这些细节。

显然,我们可以构造第二个类似的页面,使得FirstApp呈现完全不同的初始化形态,在一起都是一个全新Web机制在推动,我们现在可以看到,每一个可执行文件,应该对应应该初始化Web页面,即“ExeName.index,html”,通过这个初始化页面,应用系统的后续功能会以Web为主导逐渐展开。接下来,我们会看到,FirstApp如何支撑一款现代浏览器,事实上,我们已经看到了这一点(浏览器子窗口模式)。