我正在重写一个小型 VB6 应用程序/工具,其工作是安装一些旧版 VB6 应用程序的最新版本。旧版 VB6 应用程序是一个 ActiveX DLL,它被构建并打包到一个可执行安装程序中(一些 Inno Setup 脚本构建一个名为 的安装程序companynameSetup.exe
)。
正在重写的旧版 VB6 应用程序:
- 杀死所有消耗 ActiveX DLL 的进程(跨所有登录用户)
- 卸载当前的 ActiveX DLL
- 安装新版本的 ActiveX DLL
- 可以使用禁用 UI 的命令行参数执行
重写后的 C# 应用程序也完成了上述所有工作。唯一的区别(除了焕然一新的外观)是,无论有无 UI,VB6 代码都不会触发任何 UAC 提示:
Shell(pathAndFileName, vbNormalFocus)
但是此代码确实为安装程序可执行文件打开了 UAC(卸载程序首先运行并且不提示):
var startInfo = new ProcessStartInfo(path, args);
using (var process = Process.Start(startInfo))
{
while (!process.HasExited && _timerTicks < _timeoutTicks) Thread.Sleep(100);
//... (log stuff, handle timeout, etc.)
}
这是作为计划任务运行后的日志文件:
2013-06-12 21:49:00.8555 | Info | AutoDeploy.App | COMPUTER : somedomain\someadminuser | StartUp. ShowUI=False; TimeOut=100 |
...
2013-06-12 21:50:40.4447 | Trace | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Installer timer interval has elapsed (ticks: 99). |
2013-06-12 21:50:41.4446 | Trace | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Installer timer interval has elapsed (ticks: 100). |
2013-06-12 21:50:41.4602 | Warn | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Process execution has timed out. Process may be hung. |
该过程必须使用 UAC,因为如果我使用 GUI 手动运行它,一切都会在几秒钟内运行(在确定 UAC 之后)。因此 VB6 代码可以在一夜之间无人看管地运行,而重写的、新的和改进的(实现日志记录、失败通知、所有有趣的东西!)C# 应用程序不能。那么VB6是如何受到关注的呢?
所以问题是,我如何安排安装程序在无人看管的情况下运行,而不会让 UAC 搞砸?如果安排任务应该修复它,那么应该如何设置任务,我需要从我的程序集中添加/删除什么特别的东西才能让它工作?
编辑
解决方案很简单:
var startInfo = new ProcessStartInfo(path, args) { UseShellExecute = False };