我正在重寫一個小型的VB6應用程序/工具,其工作是安裝一些傳統VB6應用程序的最新版本。傳統的VB6應用程序是一個構建並打包到可執行安裝程序中的ActiveX DLL(某些Inno Setup腳本通過名稱companynameSetup.exe
構建安裝程序)。C#進程vs VB6 Shell vs UAC
舊版VB6應用程序被改寫:
- 殺死消耗的ActiveX DLL(在所有已登錄的用戶)
- 卸載當前的ActiveX DLL
- 安裝的ActiveX DLL的新版本的所有進程
- 可以與禁用UI
重寫的一個命令行參數來執行C#應用程序也完成了以上所有內容。唯一的區別(從全新的外觀分開),是不論有/無用戶界面,VB6的代碼不會觸發任何UAC提示:
但這種代碼確實帶來了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 };
這是很清楚你想解決什麼問題。如果是「我不想要UAC提示」,那麼,不,這不是一個選項。如果是「我不需要管理員權限」,那麼您的程序名稱就很重要。如果它包含諸如「setup」或「upgrade」之類的詞,那麼Windows將猜測它是那種可能需要提升並且顯示UAC提示的程序。你通過包含一個使用「asInvoker」的清單來避免這種情況。如果它是「我在無人看管的操作中獲得UAC提示」,那麼您可以使用計劃任務解決該問題。 –
@HansPassant對不起,如果我不夠清楚:「我不想UAC提示」,的確如此。如果它不是一個選項,那麼VB6代碼如何在不觸發UAC提示符下運行相同的可執行文件的情況下運行?如果必須的話,我會在VB6中編寫流程啓動部分,並在'unsafe'塊中調用它。但是如果UAC沒有辦法,那麼*我怎麼沒有從運行完全相同的可執行文件的VB6代碼獲得UAC提示?就UAC而言,VB6是否處於雷達之下? –
VB6程序被視爲傳統程序,因爲它沒有清單。它所做的一切都是*重定向*,所以它不會造成任何麻煩。註冊表寫入HKLM將重定向到HKCU。文件寫入受保護的目錄被重定向到一個孤立的目錄。如果這個程序真的有效,那麼你實際需要的UAC提升的可能性非常低。 –