我有一个每10分钟运行一次的Windows服务,并检查以确保我们软件的所有正确部分都已安装并且是最新的。每次服务执行时,它都使用以下函数来安装可执行文件:
public static bool InstallControlPanel()
{
try
{
//this will change
string sSetupFile = @"C:\Projects\SyncAgentV2\SyncAgentV2.ControlPanel.Installer\SyncAgentV2.ControlPanel.Installer\Express\SingleImage\DiskImages\DISK1\setup.exe";
if (!System.IO.File.Exists(sSetupFile))
{
Debug.WriteLine("Service Installer doesn't exist.");
return false;
}
Process oProcess = new Process();
oProcess.StartInfo.ErrorDialog = true;
oProcess.StartInfo.UseShellExecute = true;
oProcess.StartInfo.Arguments = "/s /v/qn";
oProcess.StartInfo.FileName = sSetupFile;
oProcess.Start();
oProcess.WaitForExit();
return true;
}
catch (Exception oEx)
{
Debug.WriteLine(oEx);
return false;
}
}
当我从服务调用此方法时,它会运行并继续执行所有步骤,返回true,但它不会安装可执行文件。我可以从WPF调用此方法,它可以工作,所以问题必须是服务调用它的方式。
目前,该服务已设置为以本地系统身份登录。我怀疑服务无法以我想要的方式运行,或者我需要它以不同的用户身份登录。有人可以验证这一点,还是指向不同的方向?
编辑:这种方法有效,但是当我从服务中调用它时却不行。
答案 0 :(得分:2)
你是否在win7下运行你的进程?安装程序是否有任何错误退出代码 在事件日志中? 可能您的安装程序需要显示UI,并且患有Session 0 isolation。
由于进程是由Windows服务启动的 - 它与当前登录的用户隔离。您需要在当前运行安装程序 登录用户的上下文。有一个WinAPI函数 - CreateProcessAsUser / CreateProcessWithToken。不幸的是,这些函数不存在于.net基类库中,必须通过PInvoke调用。这是一篇很棒的帖子,描述了how to implement wrapper for launching any command in user context。