如何使用Visual Studio将传统桌面程序转制为UWP程序

UWP Platform

Desktop Bridge是内置于平台中的基础架构,借助它,可以使用现代化的 Windows 应用包来分发Windows Forms、WPF 或 Win32 桌面应用或游戏。

优点

通过将Windows 桌面程序转制为Windows 10 UWP应用包有下面的优点:

  • 简化部署。使用此Desktop Bridge的应用和游戏都具有出色的部署体验。 这体验确保用户可以放心地安装应用,并对其进行更新。如果用户选择卸载应用,则将完全删除它,不会留下任何痕迹。 这能减少编写设置体验的时间,并使用户使用最新应用。

  • 自动更新和许可。你的应用能够参与 Microsoft Store 的内置许可和自动更新设施。 自动更新是高度可靠和高效的机制,因为仅下载文件的已更改部分。

  • 扩大覆盖范围并简化盈利过程。选择通过 Microsoft Store进行分发可将覆盖范围扩大至数以百万的 Windows10用户,这些用户可以通过当地支付选项获取应用、游戏和应用内商品。

  • 添加 UWP 功能。你可以按照自己的节奏向应用的程序包添加 UWP 功能,如 XAML 用户界面、动态磁贴更新、UWP 后台任务、应用服务以及许多其他功能。

  • 拓展跨设备用例。通过使用桥,可以将代码逐渐迁移到通用 Windows 平台,以覆盖所有的 Windows10 设备,包括手机、Xbox One 和 HoloLens。

环境需求

Desktop Bridge是在 Windows 10 版本 1607 中引入,它仅可用于面向 Windows 10 周年更新(10.0;版本 14393)Visual Studio 更高版本的项目中。

准备

开发者在将应用打包为UWP引用之前需要清理下面相关问题的代码:

  • 你的应用使用早于 4.6.1 的 .NET 版本。 仅 .NET 4.6.1 受支持。 在进行打包之前,需要将应用重定目标到 .NET 4.6.1。

  • 应用始终使用提升的安全权限运行。 你的应用需要在以交互用户身份运行时工作。 从 Windows 应用商店安装应用的用户可能不是系统管理员,因此需要应用以提升的权限运行意味着它无法为标准用户正确运行。

  • 应用需要内核模式驱动程序或 Windows 服务。 该桥适用于应用,但不支持内核模式驱动程序或需要在系统帐户下运行的 Windows 服务。 使用后台任务,而不是 Windows 服务。

  • 在进程内将应用的模块加载到不在 Windows 应用包中的进程。 不允许此操作,这意味着不支持进程中扩展,如 shell 扩展。 但是,如果你在同一个程序包中有两个应用,则可以在它们之间执行进程间通信。

  • 应用使用自定义的应用程序用户模型 ID (AUMID)。 如果进程调用 SetCurrentProcessExplicitAppUserModelID 以设置其自己的 AUMID,则它可能仅使用应用模型环境/Windows 应用包为其生成的 AUMID。 无法定义自定义 AUMID。

  • 应用修改 HKEY_LOCAL_MACHINE (HKLM)注册表配置单元。 应用的任何创建 HKLM 键或打开一个键以进行修改的尝试都会导致拒绝访问失败。 请记住,应用具有其自己的注册表专用虚拟化视图,因此用户范围和计算机范围的注册表配置单元(即 HKLM 的本质)的想法不适用。 你将需要找到另一种方法来实现 HKLM 的用途,如改为写入 HKEY_CURRENT_USER (HKCU)

  • 应用使用 ddeexec注册表子项作为启动另一个应用的方式。 改为使用应用程序包清单中的各种可激活扩展配置的 DelegateExecute 谓词处理程序之一。

  • 你的应用会写入 AppData文件夹或注册表,目的是与其他应用共享数据。 转换后,AppData将重定向到本地应用数据存储,该存储是每个 UWP 应用的专用应用商店。

  • 你的应用将写入 HKEY_LOCAL_MACHINE注册表配置单元的所有条目都将重定向到隔离的二进制文件中,你的应用写入 HKEY_CURRENT_USER注册表配置单元的任何条目都将按用户、按应用放入专用位置中。 有关文件和注册表重定向的更多详细信息,请参阅在桌面桥幕后。

  • 使用不同的进程间数据共享方式。 有关详细信息,请参阅存储和检索设置以及其他应用数据。

  • 应用写入应用的安装目录。 例如,应用写入与你的 exe放置在同一个目录中的日志文件。 此操作不受支持,因此你需要找到另一个位置,如本地应用数据存储。

  • 应用安装需要用户交互。 应用安装程序必须能够在无提示的情况下运行,并且它必须安装默认不在干净操作系统映像中的所有先决条件。

  • 应用使用当前工作目录。 在运行时,打包的桌面应用不会得到你之前在桌面 .LNK 快捷方式中指定的相同工作目录。 如果具有正确的目录对应用正常运行很重要,你需要在运行时更改 CWD。

  • 应用需要UIAccess。 如果应用程序在UAC清单的 requestedExecutionLevel 元素中指定UIAccess=true,则当前不支持转换为 UWP。 有关详细信息,请参阅 UI 自动化安全概述。

  • 应用公开COM对象。 来自程序包内的进程和扩展可以注册并使用 COMOLE服务器,进程内和进程外 (OOP) 皆可。 创意者更新添加了打包的COM支持,它提供注册 OOP COMOLE服务器(现在这些服务器在包外部可见)的功能。 请参阅对桌面桥的COM 服务器OLE 文档支持。

  • 打包的 COM支持适用于现有的COM API,但不适用于依赖直接读取注册表的应用程序扩展,因为打包的 COM 位于一个专用位置。

  • 应用公开GAC程序集以供其他进程使用。 在当前版本中,应用无法公开 GAC 程序集以供来自 Windows 应用包外部可执行文件的进程使用。 来自程序包内的进程可以照常注册和使用 GAC 程序集,但它们在外部将不可见。 这意味着,OLE 等互操作方案在被外部进程调用时不起作用。

  • 你的应用正以不受支持的方式链接C 运行时库 (CRT)Microsoft C/C++ 运行时库提供用于为 Microsoft Windows 操作系统编程的例程。 这些例程自动执行许多不采用 C 和 C++ 语言提供的常见编程任务。 如果你的应用利用 C/C++ 运行时库,你需要确保它以受支持的方式链接。
    其他具体内容参考微软官方文档:Windows 开发中心

开始

这里以一个简单的WPF Helllo World程序来示例。
运行环境:

  • Windows 10 1803
  • Visual Studio Professional 2017 15.7.3
  1. 新建WPF程序。
    注意,这里需要将.NET Framework的版本选择为4.6.1以上,如果系统中没有4.6.1以上的版本,通过Visual Studio Installer来以组件的形式安装高版本的.NET Framework
    新建WPF程序
  2. 填充代码
    MainWindow.xaml文件中填写一个Button以及其点击的事件。
<Window x:Class="HelloWorldDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelloWorldDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button HorizontalAlignment="Center" 
                VerticalAlignment="Center" 
                Content="Click Me" 
                Click="Button_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs中填写View视图中Button的逻辑事件,这里,我们简单地将这个Button点击事件处理为弹出一个Hello World!的消息框。

using System.Windows;

namespace HelloWorldDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello World!");
        }
    }
}

  1. 打包前测试运行
    在打包为UWP程序之前,我们执行上面新建的WPF程序,效果如图。
    测试运行

    正如我们所写的那样,点击这个Button,能弹出Hello World!的消息框了。
  2. 新建UWP打包项目
    在当前的解决方案上右键Add->New Project,然后Windows Universal内容中选择Windows Application Packaging Project
    [站外图片上传中...(image-215821-1528040900571)]
    新建打包项目

    继续选择Target versionMinimum version,这里以最低15063,最高17143为例子,如果选择了系统中没有的Windows SDK的,会提示下载SDK
    SDK选择
  3. 添加引用
    在新建的UWP打包项目的Applications右键来添加同解决方案下WPF项目的引用。
    添加引用

    添加引用
  4. 设置入口点
    Applicatons下刚添加的引用设置为入口点。
    [站外图片上传中...(image-6444f5-1528040900571)]
  5. 重新构建
    解决方案右键Rebuild启动重新构建,一般情况下没有出错即可。
  6. 创建App包
    打包程序右键,Store->Create App Packages...,在弹出的对话框中选择打包为Sideloading 旁加载
    [站外图片上传中...(image-2a47ef-1528040900571)]
    旁加载

    然后,等待打包完成。
  7. UWP测试运行
    在项目文件夹中AppPackagesWapProjTemplate_1.0.0.0_Debug_Test中可以看到,其中有cer证书文件,appxbundleUWP安装程序文件,Add-AppDevPackage.ps1PowerShell安装批处理,以及其他文件。
    打包

这里,右键这里PowerShell批处理文件,选择使用PowerShell 运行,安装过程中提示需要管理员权限,全部Y即可。

打包

安装完成后即可在开始菜单看到刚打包的UWP程序,点击运行。


PowerShell 安装

执行效果和之前运行的一样。

参考文献:

  • 微软官方开发文档
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容