如何启动从Windows服务运行bat文件的进程

时间:2016-08-23 00:30:11

标签: c# windows-services

尝试从Windows服务运行bat文件。 这是代码:

try
            {
                SecureString securePwd = new SecureString();
                foreach (char c in pwd)
                {
                    securePwd.AppendChar(c);
                }
                Process process = new Process();
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.FileName = @"CMD.exe";  //The file in that DIR.
                process.StartInfo.WorkingDirectory = @"C:\";
                process.StartInfo.Arguments = @"/C " + filePath;
                process.StartInfo.Verb = "runas";
                process.StartInfo.UserName = user;
                process.StartInfo.Password = securePwd;
                process.Start();
            }
            catch (Exception ex)
            {
                EventLog myEventLog = new EventLog { Source = "MoC LaneUpdate" };
                myEventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
            }

我已经验证了在非服务中运行时,相同的代码是有效的。我也没有收到错误消息,但.bat文件没有运行,至少它在我当前的用户会话中似乎没有。我的文件是在后台会话中运行的吗?如何在startinfo中指定的用户中运行批处理文件?

1 个答案:

答案 0 :(得分:0)

对于Windows服务运行,服务创建用户进程需要桌面应用程序。

服务是在会话0 中创建的,其中不允许图形界面 它们不会显示,正在必要时在用户登录的部分创建一个进程(0除外)。

为此,必须使用windows api的资源。

以下vb.net中的示例。

ps:对不起我的英语。

 Try

        Dim UserTokenHandle As IntPtr = IntPtr.Zero
        Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
        Dim StartInfo As New WindowsApi.STARTUPINFOW

        'obtain an access token(handle) for the session that the user logged in is using.
        WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)

        'widows specification for the process that will be created
        StartInfo.cb = CUInt(Runtime.InteropServices.Marshal.SizeOf(StartInfo))

        'create a new process to run on the user session represented by UserTokenHandle that was obtained in WTSQueryUserToken
        WindowsApi.CreateProcessAsUser(UserTokenHandle,"C:\FILE_TO_RUN.EXE", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)

        'checks whether the UserTokenHandle is nonzero
        If Not UserTokenHandle = IntPtr.Zero Then
            WindowsApi.CloseHandle(UserTokenHandle)
        End If

    Catch ex As Exception
       throw
    End Try

参考文献: https://www.2brightsparks.com/resources/articles/understanding-windows-sessions.pdf

http://blogs.technet.com/b/askperf/archive/2007/04/27/application-compatibility-session-0-isolation.aspx