-1

我正在重写一个小型 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 };
4

1 回答 1

1

像框架中的大多数东西一样,.Net 的ProcessStartInfo类是一大堆……代码。它包装了大量的 Win32 结构和调用。

Classic VB 的Shell()功能是一个重量轻得多的包装器WinExec() In Kernel32,它又是CreateProcess() In Kernel3232 位和 64 位 Windows 中的一个薄包装器。

我猜你真正想要的是在ProcessStartInfo不调用 Shell32 中的旧安装程序检测启发式的情况下启动一个外部程序。我能想到两种选择:

  • 通过以下方式向第二个程序添加一个清单,将其标记为“Vista 感知”:<requestedExecutionLevel level="asInvoker" uiAccess="false"/>

  • 告诉它不要使用ShellExecute(),而是CreateProcess()先设置:Process.UseShellExecute = false;

并且“是的,弗吉尼亚,VB6 程序可以(并且应该)有一个清单。”

我的 C# 生锈了,您可以查阅文档:ProcessStartInfo.UseShellExecute Property

于 2013-06-12T20:14:30.227 回答