2010-10-01 127 views
5

嗨,在Windows 7上無法從Windows服務啓動桌面應用程序

我有Windows 7上的C#WCF Windows服務以具有管理權限的用戶身份登錄。 我想在服務啓動後啓動桌面應用程序。我發現的所有討論都是關於Windows工作站和桌面......我創建了一個單獨的線程,設置線程工作站和桌面,並嘗試啓動桌面應用程序。 當我使用asp.net開發服務器從VS2010啓動它時,代碼有效,但如果它是從服務啓動的,則沒有錯誤,但進程未啓動。我嘗試以不同的用戶身份啓動進程,並嘗試調用CreateProcessWithLogonW(以前將startInfo.lpDesktop設置爲「winsta0 \ default」)。在這兩種情況下,我都有processId返回,但無法看到桌面應用程序。 有人能幫我看看哪裏出了錯?

public class ExternalProcess 
{ 
    const int READ_CONTROL = 0x20000; 
    const int WRITE_DAC = 0x40000; 
    const int DESKTOP_WRITEOBJECTS = 0x80; 
    const int DESKTOP_READOBJECTS = 0x1; 

    private Process extProcess; 
    private string sFilePath = ""; 

    [DllImport("user32.dll")] 
    private static extern bool SetThreadDesktop(IntPtr hDesktop); 
    [DllImport("user32.dll")] 
    static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,bool fInherit, uint dwDesiredAccess); 
    [DllImport("user32.dll")] 
    private static extern IntPtr GetProcessWindowStation(); 
    [DllImport("user32.dll")] 
    private static extern IntPtr OpenWindowStation(string lpszWinSta, bool fInherit, ACCESS_MASK dwDesiredAccess); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SetProcessWindowStation(IntPtr hWinsta); 

    public bool StartProcess(string filePath) 
    { 
     sFilePath = filePath; 
     Thread t = new Thread(new ThreadStart(Thread_StartProcess)); 
     t.Start(); 

     return true; 
    } 

    private void Thread_StartProcess() 
    { 
     IntPtr hwinstaSave; 
     IntPtr hwinsta, hwinsta2; 
     IntPtr hdesk; 

     hwinstaSave = GetProcessWindowStation(); 
      System.Console.WriteLine("GetProcessWindowStation Lasterror= " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("GetProcessWindowStation hwinstaSave= " + hwinstaSave.ToString()); 
     //hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.GENERIC_EXECUTE | ACCESS_MASK.DESKTOP_CREATEWINDOW | ACCESS_MASK.DESKTOP_CREATEMENU | ACCESS_MASK.DESKTOP_SWITCHDESKTOP | ACCESS_MASK.DESKTOP_WRITEOBJECTS); 
     hwinsta = OpenWindowStation("winsta0", false, ACCESS_MASK.WINSTA_ALL_ACCESS); // when call from windows service OpenWindowStation returns 0 
      System.Console.WriteLine("OpenWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("OpenWindowStation hwinsta= " + hwinsta.ToString()); 
     hwinsta2 = SetProcessWindowStation(hwinsta); 
      System.Console.WriteLine("SetProcessWindowStation lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("SetProcessWindowStation hwinsta2= " + hwinsta2.ToString()); 
     hdesk = OpenDesktop("default", 0, true, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS); 
      System.Console.WriteLine("OpenDesktop lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("OpenDesktop hdesk= " + hdesk.ToString()); 
     bool Success = SetThreadDesktop(hdesk); 
      System.Console.WriteLine("SetThreadDesktop lasterror = " + Marshal.GetLastWin32Error().ToString()); 
      System.Console.WriteLine("SetThreadDesktop Success= " + Success.ToString()); 

     try 
     { 
      extProcess = new Process(); 

      extProcess.StartInfo.FileName = sFilePath; 
      extProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal; 

      if (extProcess.Start()) 
       System.Console.WriteLine("Process started "); 
      else 
       System.Console.WriteLine("Not started!"); 
     } 
     catch (Win32Exception e) 
     { 
      System.Console.WriteLine("Start {0} failed. Error: " + e.Message); 
     } 
    } 

} 
+0

完整的源代碼示例工作任何有關它的最終解決方案? – Kiquenet 2013-07-11 11:37:37

回答

1

Perhapse這有助於:http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx

心連心

馬里奧

+0

Thx,我已經讀過,試圖檢查服務中的「允許服務與桌面交互」複選框,更改運行服務的用戶...,對於特定用戶,不允許使用複選框,我嘗試設置它在註冊表中手動,但沒有結果... – Jovan 2010-10-01 11:20:03

+0

我更多的是指這個聲明:「重要服務不能直接與Windows Vista的用戶交互,因此,不應使用標題爲」使用交互式服務「一節中提到的技術在新的代碼中。「 - 似乎從Windows Vista開始直接從服務器與用戶進行交互(這意味着,Vista,7和Server 2008,我猜!)不再是可能的。它在調試器中工作,因爲調試器不是真正的服務! – 2010-10-01 11:55:56

+0

好的,我很害怕那部分。這意味着必須嘗試不同的設計。非常感謝。 – Jovan 2010-10-01 12:02:30

4

互動Windows服務在Windows Vista中收到一個以安全爲中心的改造。服務現在運行在孤立的「會話0」中,並且不能將窗口輕鬆注入到交互式用戶會話中。上面的代碼將在會話0中創建GUI元素,即使在選中「允許服務與桌面交互」的情況下,它們也不會顯示在任何用戶的桌面上。

有關Windows服務限制的更多詳細信息,請參見this technical document from Microsoft

0

我現在正處在這個權利當中,我知道UltraVNC這樣做,所以我會看看代碼。我現在不是100%肯定答案,當我知道我會更新這篇文章。

的要點是你做了一個CreateProcessAsUser,然後該過程可能必須做OpenInputDesktop,然後是一個SetThreadDesktop,但是像我無法讓它工作。

相關問題