2012-07-06 101 views
1

我使用System.Diagnostic.Process類來使用.Net WCF Web服務在我的服務器pc上啓動進程。他們開始順利,我可以看到他們從任務管理器運行,但沒有窗口顯示。你們如何認爲我能克服這個問題?如何從.net Web服務啓動應用程序?

+0

服務不能交互(由於許多原因,安全性和強大首先)。檢查[這篇文章在這裏](http://stackoverflow.com/questions/4516200/how-can-a-windows-service-start-a-process-when-a-timer-event-is-raised)for解決方法。 – 2012-07-06 12:08:23

+0

你可以發佈一些代碼,顯示你如何開始這個過程 – 2012-07-06 12:09:54

回答

3

如果要顯示GUI並且用戶能夠與其交互,則必須啓動的互動過程。目前,您的網絡服務可能並非如此。

Start a windows service and launch cmd

+0

啊,即使我編寫這個代碼,你仍然可以作爲一個服務對我沒有任何用處,但你幾乎打敗我,以相同的答案 – hometoast 2012-07-06 12:25:04

0

你說的是一個Web服務,所以它也可能作爲Windows服務運行? 在這種情況下,您可以啓動流程,但您永遠不會看到任何表單。

即使沒有用戶登錄,Windows服務也可以在您的計算機上運行。 因此,它永遠不知道要在哪裏顯示要運行的應用程序!

您可以使用名爲「允許與桌面交互」(或類似的)的設置來擺弄,但服務並不意味着以這種方式使用。

+0

我已經建議使用該設置的解決方案,但我不喜歡它:/你聽起來像我不應該這樣做,所以什麼是替代方式在遠程機器上啓動應用程序?順便說一下,我使用的遠程機器是WindowsServer2008。 – 2012-07-06 12:15:11

+0

如果我使用批處理文件啓動應用程序並通過Web服務啓動批處理文件,該怎麼辦? – 2012-07-06 12:37:05

+0

可能不會工作,因爲啓動的進程將是(不可見的)批處理文件的子進程! 但是真的不知道這一點.. – 2012-07-06 12:42:26

1

你不應該這樣做,但是......

您可以在啓動程序的用戶在當前會話

IntPtr UserTokenHandle = IntPtr.Zero; 
WTSQueryUserToken (WTSGetActiveConsoleSessionId(), ref UserTokenHandle); 

PROCESS_INFORMATION ProcInfo = new PROCESS_INFORMATION(); 
STARTUPINFOW StartInfo = new STARTUPINFOW(); 
StartInfo.cb = Convert.ToUInt32(System.Runtime.InteropServices.Marshal.SizeOf(StartInfo)); 


CreateProcessAsUser (UserTokenHandle, @"C:\dir\MyApp.exe", 
    IntPtr.Zero, 
    IntPtr.Zero, 
    IntPtr.Zero, 
    false, 
    0, 
    IntPtr.Zero, 
    null, 
    ref StartInfo, 
    ref ProcInfo); 

if (!(UserTokenHandle == IntPtr.Zero)) 
{ 
    CloseHandle (UserTokenHandle); 
} 

必需的進口和結構:

[DllImport("kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId", SetLastError = true)] 
public static extern uint WTSGetActiveConsoleSessionId(); 

[DllImport("Wtsapi32.dll", EntryPoint = "WTSQueryUserToken", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool WTSQueryUserToken (uint SessionId, ref IntPtr phToken); 

[DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool CloseHandle ([InAttribute()] 
    IntPtr hObject); 

[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUserW", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool CreateProcessAsUser (
    [InAttribute()] 
    IntPtr hToken, 
    [InAttribute(), MarshalAs(UnmanagedType.LPWStr)] 
    string lpApplicationName, System.IntPtr lpCommandLine, 
    [InAttribute()] 
    IntPtr lpProcessAttributes, 
    [InAttribute()] 
    IntPtr lpThreadAttributes, 
    [MarshalAs(UnmanagedType.Bool)] 
    bool bInheritHandles, uint dwCreationFlags, 
    [InAttribute()] 
    IntPtr lpEnvironment, 
    [InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)] 
    string lpCurrentDirectory, 

ref STARTUPINFOW lpStartupInfo, 

ref PROCESS_INFORMATION lpProcessInformation); 

[StructLayout(LayoutKind.Sequential)] 
public struct SECURITY_ATTRIBUTES 
{ 
    public uint nLength; 
    public IntPtr lpSecurityDescriptor; 
    [MarshalAs(UnmanagedType.Bool)] 
    public bool bInheritHandle; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct STARTUPINFOW 
{ 
    public uint cb; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public string lpReserved; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public string lpDesktop; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public string lpTitle; 
    public uint dwX; 
    public uint dwY; 
    public uint dwXSize; 
    public uint dwYSize; 
    public uint dwXCountChars; 
    public uint dwYCountChars; 
    public uint dwFillAttribute; 
    public uint dwFlags; 
    public ushort wShowWindow; 
    public ushort cbReserved2; 
    public IntPtr lpReserved2; 
    public IntPtr hStdInput; 
    public IntPtr hStdOutput; 
    public IntPtr hStdError; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct PROCESS_INFORMATION 
{ 
    public IntPtr hProcess; 
    public IntPtr hThread; 
    public uint dwProcessId; 
    public uint dwThreadId; 
} 
+0

。我應該使用其他策略。 – 2012-07-06 12:36:08

+0

否。該代碼將執行應用程序作爲當前登錄會話中的用戶。 – hometoast 2012-07-06 13:04:55

+0

我試過這段代碼,但它也沒有工作:/進程啓動時沒有任何gui:/ – 2012-07-06 14:42:41

相關問題