ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 2167|回复: 3

[原创] 无商业证书场景下的VSTO分发方案

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-6-29 11:28 | 显示全部楼层 |阅读模式
前言本文旨在优化无商业证书场景下的VSTO分发方案,目标是实现用户端的简单安装、自动更新。
项目介绍我花费几个月时间断断续续折腾出了一个Excel VSTO,曾在分发阶段遭遇了许多问题。
虽然麻烦不断,但通过不断努力(地搜索),最终得到了一套比较完善的方案,遂撰文分享一二。
主要思路:在VSTO的ClickOnce之前套一层安装器,进行证书导入等操作,之后自动下载VSTO安装包、自动运行。
安装测试
开源地址  
对于非商业项目,我没有任何兼容性顾虑,项目中的.net Framework和Interop.Excel都选择了最新版本,因此可能会不兼容许多低版本系统或office。
但是,不用担心,事实上,即便顾及到兼容性,我的分发思路也应该是通用的。
Excel VSTO部署简介直接在Visual Studio中点击“发布”,会得到如下结构的文件(微软官方的图,使用了Outlook)。




publishfolderstructure


这种发布方式被称为“ClickOnce”:
Deploy an Office solution by using ClickOnce - Visual Studio​docs.microsoft.com  
注:
官网还介绍了以Windows Installer打包发布VSTO的方式,这种方式不支持自动升级。
一些第三方打包工具,如AdvancedInstaller,我不确定它们能否打包出可自动升级的VSTO。

不与如今的各种应用商店作比较,这种发布方式看起来是非常优秀的。
你可以指定用户从你的网站下载setup.exe,打开后安装器会自动从你设定的网络路径拉取所需文件,
安装完成之后它能够保持自动更新……这一切看起来都相当完美,但前提是你得有一个已经获取系统授信的代码证书
我也曾尝试从Comodo申请个人代码证书,但是,经过一阵沟通之后,个人代码证书似乎需要进行Face-to-Face验证,而我身在中国……
如果使用自己的测试证书之类的进行ClickOnce发布,并妄图将安装源设定在你的网站,甚至还妄想它能够保持自动更新……那么,你会得到这个:




截图来自网络


当然,这张图是我在网上随便找的,我自己的分发问题已经彻底解决了,所以不会再出现这个界面。
网络上的方案为了兼顾简易安装与自动更新,我翻阅了网络上的各种Q&A,
答案主要分为两派:“自制证书派”和“改注册表派”(以下分别简称“证书派”与“注册表派”)。
证书派:自制代码证书,让用户导入你的证书,参见
通商软件MAX
的文章
注册表派:注入注册表,修改用户机器的信任提示设置,参见
微软官方文档
证书派的导入自制证书需要让用户多出一步操作,注册表派的注入注册表也需要让用户在安装VSTO之前运行一个事先写好的脚本。
我的分发方案我的思路非常简单,如开头所述,
就仅仅是在VSTO的ClickOnce之前加一层安装器,进行证书导入等操作,之后自动下载VSTO安装包、自动运行。
  • 自制证书
    工具任选,自制一个代码证书,最终效果差不多是这样:



    自制证书

  • 给VSTO签名



    使用自制证书给VSTO签名

  • 直接发布
    虽然你使用了不受用户信任的自制证书,但你可以假装它是正规商业证书,直接把你的VSTO发布到站点上就是了。
    到此为止,你已经成功获得了一个用户无法安装的VSTO
  • 自行制作一个安装器
    它的名字可能会类似于“Installer.exe”,既可以是命令行脚本也可以是拥有华丽界面的WPF程序,这些都不重要,你可以随心所欲。
    重要的是,它应该是一个单文件软件,开袋即食的那种单文件软件,以方便用户下载、直接点击运行。
    它的作用主要有以下三点,我将以代码说明:
    • 尝试下载自制证书,并导入用户机器
        private async Task CertAsync()  {      string localFullName = $"{DownloadPath}sn.cer";      Uri uri = new Uri("http://Public.mujiannan.me/1Math/sn.cer");      await DownloadAsync(uri, localFullName);      using (X509Certificate2 myCert = new X509Certificate2(localFullName))      {          using (X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))          {              store.Open(OpenFlags.ReadWrite);              store.Remove(myCert);              store.Add(myCert);          }      }  }
    • 若证书导入失败,则尝试写入注册表
        internal static void SetTrustPromptBehavior()  {      RegistryKey key;      if (System.Environment.Is64BitOperatingSystem)      {          key=Microsoft.Win32.Registry.LocalMachine.CreateSubKey(              @"SOFTWARE\Wow6432Node\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel");      }      else      {          key=Microsoft.Win32.Registry.LocalMachine.CreateSubKey(              @"SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel");      }      key.SetValue("MyComputer", "Enabled");      key.SetValue("LocalIntranet", "Enabled");      key.SetValue("Internet", "Enabled");      key.SetValue("TrustedSites", "Enabled");      key.SetValue("UntrustedSites", "Enabled");      key.Close();  }
    • 下载VSTO安装文件,运行
        private async Task SetUpAsync()  {      string localFullName = $"{DownloadPath}setup.exe";      Uri uri = new Uri("http://Public.mujiannan.me/1Math/setup.exe");      Reportor.Report($"下载{uri.AbsolutePath}至{localFullName},请耐心等待...");      await DownloadAsync(uri, localFullName);      System.Diagnostics.Process.Start(localFullName);  }
下面是我制作的安装器的后台主方法:
    public async Task StartInstallerAsync()    {        //进行两步操作(导入证书、注入注册表)        //优先选择导入证书,如果证书导入失败,则转而尝试注册表        //当两步操作都失败时,向外传递异常信息        string errInfo = string.Empty;//用于记录错误信息        bool trustSuccess = false;//标记证书是否导入成功        try        {            await CertAsync();//导入证书            trustSuccess = true;        }        catch (Exception Ex)        {            errInfo += Ex.Message;//记录证书导入错误消息            Reportor.Report("错误:证书导入失败,请联网并使用管理员权限运行");        }        if (!trustSuccess)        {            try//事实上,如果上一步证书没导入成功,再来尝试写注册表也基本上是无济于事的            {                Reg.SetTrustPromptBehavior();//写入注册表                trustSuccess = true;            }            catch (Exception Ex)            {                errInfo += Ex.Message;                this.Reportor.Report("错误:注册表写入失败,请尝试使用管理员权限运行");            }        }        if (trustSuccess)//当导入证书与注册表写入有任何一项成功时,都可以正常执行下载、安装的操作        {            await SetUpAsync();        }        else        {            await Task.Delay(2000);//显示最终的错误信息前,留点时间告诉用户要用管理员权限运行            throw new Exception(errInfo);//别在本地存日志之类的,直接显示出来吧……        }    }后记作为一名非科班出身的编程初学者,一些像VSTO分发之类在专业开发者眼中可能根本不能算是问题的问题也会成为我的拦路虎。
我相信专业的开发者们总能很自然地处理好这些事情,但我知道,还有一些跟我一样自学入门的开发者们在面对这些问题时也是头疼不已。
希望这篇文章可以帮助到一些人处理好无商业证书场景下的VSTO分发问题。
学习路上,一帆风顺!

TA的精华主题

TA的得分主题

发表于 2019-6-29 12:26 来自手机 | 显示全部楼层
没有证书应该也可以运行吧

TA的精华主题

TA的得分主题

发表于 2019-8-2 19:57 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
高手,膜拜啊 ,中年大叔学习了。

TA的精华主题

TA的得分主题

发表于 2022-8-25 11:44 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
不需要如此复杂,看我的帖子,试试看
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-19 17:23 , Processed in 0.026549 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表