繁体   English   中英

在服务的OnStart代码块中启动进程失败

[英]Starting a process fails in OnStart code block of a service

我只想打电话

Process.Start("notepad.exe");

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

非常感谢。

[ 更新 ]

我在登录选项卡上打了一个勾号以允许交互式桌面后,使它工作。 但是我不知道这到底意味着什么? 如果总是要求我接受在“交互式桌面检测”面板中查看消息的计算机,该如何计划在任何计算机上运行任务?

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

请记住,从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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM