2012-07-08 44 views
0

我只是想打电话启动过程中的服务的OnStart代码块失败

Process.Start("notepad.exe"); 

在服务启动时;但它根本不起作用。在我选择在Windows服务管理器中启动服务后,没有任何记事本被调用。

谢谢你很多。

[UPDATE]

我把它放在一个选中标记在登录选项卡允许交互式桌面后工作。但我不知道这是什么意思?如果我总是要求我接受在“交互式桌面检测”面板中查看消息,我该如何计划在任何计算机上运行任务?

+0

** **大多数这个probabbly权限问题。考虑到你试图从服务中运行* exe *文件,至少默认权限可能*不可能。 – Tigran 2012-07-08 14:27:22

+0

您的服务能否与桌面进行互动? – 2012-07-08 14:27:35

+1

@UweKeim,是的,谢谢你,它现在的作品,但它似乎总是问我与“交互式服务检测”接受查看消息(即打开记事本),非常嘈杂。我应该如何通过完全接受记事本进程的打开来关闭它? – 2012-07-08 14:36:08

回答

3

Windows服务与标准进程不同,默认情况下它不能与用户桌面交互(这是Windows操作系统的规则),因此启动进程并允许其与用户桌面进行交互您必须标记Interact与桌面选项...

请记住,从Windows Vista开始,服务在会话0下运行,并且每次该服务尝试启动该过程时都会向用户显示一个面板,让用户选择是否要运行该流程;克服这种限制(面板请求确认)的唯一方法是从服务直接与Windows API的CreateProcessAsUser功能启动进程...

看看这个功能,我已经开发了一些时间以前,即利用CreateProcessAsUser API的,并且不要求任何东西,甚至在Vista/7开始从服务的过程:

/// <summary> 
    /// LaunchProcess As User Overloaded for Window Mode 
    /// </summary> 
    /// <param name="cmdLine"></param> 
    /// <param name="token"></param> 
    /// <param name="envBlock"></param> 
    /// <param name="WindowMode"></param> 
    /// <returns></returns> 
    private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock,uint WindowMode) 
    { 
     bool result = false; 

     PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 
     SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES(); 
     SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES(); 
     saProcess.nLength = (uint)Marshal.SizeOf(saProcess); 
     saThread.nLength = (uint)Marshal.SizeOf(saThread); 

     STARTUPINFO si = new STARTUPINFO(); 
     si.cb = (uint)Marshal.SizeOf(si); 

     //if this member is NULL, the new process inherits the desktop 
     //and window station of its parent process. If this member is 
     //an empty string, the process does not inherit the desktop and 
     //window station of its parent process; instead, the system 
     //determines if a new desktop and window station need to be created. 
     //If the impersonated user already has a desktop, the system uses the 
     //existing desktop. 

     si.lpDesktop = @"WinSta0\Default"; //Default Vista/7 Desktop Session 
     si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK; 

     //Check the Startup Mode of the Process 
     if (WindowMode == 1) 
      si.wShowWindow = SW_SHOW; 
     else if (WindowMode == 2) 
     { //Do Nothing 
     } 
     else if (WindowMode == 3) 
      si.wShowWindow = 0; //Hide Window 
     else if (WindowMode == 4) 
      si.wShowWindow = 3; //Maximize Window 
     else if (WindowMode == 5) 
      si.wShowWindow = 6; //Minimize Window 
     else 
      si.wShowWindow = SW_SHOW; 


     //Set other si properties as required. 
     result = CreateProcessAsUser(
     token, 
     null, 
     cmdLine, 
     ref saProcess, 
     ref saThread, 
     false, 
     CREATE_UNICODE_ENVIRONMENT, 
     envBlock, 
     null, 
     ref si, 
     out pi); 

     if (result == false) 
     { 
      int error = Marshal.GetLastWin32Error(); 
      string message = String.Format("CreateProcessAsUser Error: {0}", error); 
      Debug.WriteLine(message); 

     } 

     return result; 
    }