简体   繁体   English

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

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

I only would like to call 我只想打电话

Process.Start("notepad.exe");

when the service starts; 服务何时开始; But it doesn't work at all. 但这根本不起作用。 No notepad is called right after I chose to start the service in the windows service manager. 在Windows服务管理器中选择启动服务后,没有记事本被调用。

Thank you a lot. 非常感谢。

[ UPDATE ] [ 更新 ]

I made it work after putting a check mark in logon tab to allow interactive desktop. 我在登录选项卡上打了一个勾号以允许交互式桌面后,使它工作。 But I don't know what does this really mean ? 但是我不知道这到底意味着什么? How can I schedule to run a task on any computer if it always asks me to accept to view the message in the Interactive Desktop Detection panel ? 如果总是要求我接受在“交互式桌面检测”面板中查看消息的计算机,该如何计划在任何计算机上运行任务?

A Windows service is different from a standard process and by default it can't interact with the user desktop(this is a rule of the Windows OS), so to launch a process and allow it to interact with the user desktop you have to flag the Interact with desktop option ... Windows服务不同于标准进程,默认情况下它无法与用户桌面进行交互(这是Windows操作系统的规则),因此要启动进程并允许其与用户桌面进行交互,您必须标记与桌面交互选项...

Bear in mind that starting from Windows Vista services are running under session 0 and every time that the service try to start the process a panel is shown to the user the let the user choose if he wants to run the process or not; 请记住,从Windows Vista服务开始在会话0下运行,并且每次服务尝试启动该过程时,都会向用户显示一个面板,让用户选择是否要运行该过程; to overcome this limitation (panel that ask for confirmation) the only way is to launch the process from the service directly with the CreateProcessAsUser function of the Windows API ... 要克服此限制(要求确认的面板),唯一的方法是直接使用Windows API的CreateProcessAsUser函数从服务启动进程。

Take a look at this function that i have developed some times ago, that make use of the CreateProcessAsUser API, and start a process from a service without asking anything even in Vista/7: 看一看我之前开发的该函数,该函数利用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