簡體   English   中英

無法從Windows 7上的Windows服務啟動桌面應用程序

[英]Cannot start desktop application from Windows service on Windows 7

嗨,

我在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);
        }
    }

}

Interactive Windows Services在Windows Vista中收到了以安全性為中心的改造。 現在,服務在隔離的“會話0”中運行,並且無法輕松地將窗口注入到交互式用戶會話中。 上面的代碼將在會話0中創建GUI元素,即使選中了“允許服務與桌面交互”,該元素也不會顯示在任何用戶的桌面上。

有關Windows服務限制的更多詳細信息,請參閱Microsoft的本技術文檔

自Windows Vista以來,該應用程序在不同的會話中打開。 因此,您不會看到該應用程序處於打開狀態,並且無法與該應用程序進行通信。 這可能會有所幫助

可以通過服務在用戶會話中啟動流程嗎?

阿西姆

也許這會有所幫助: http : //msdn.microsoft.com/zh-cn/library/ms683502%28VS.85%29.aspx

hth

馬里奧

我現在處於中間位置,我知道UltraVNC會這樣做,所以我將看一下代碼。 目前我還不確定100%的答案,當我弄清楚時,我會更新這篇文章。

要點是您要做一個CreateProcessAsUser,然后該進程可能必須先執行OpenInputDesktop然后再執行SetThreadDesktop,但就像我無法使它正常工作一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM