2013-03-24 183 views
2

我對微軟的世界有點新鮮。我已閱讀this答案和許多其他鏈接,我知道在Vista之後,Windows服務不可能與桌面交互。從Windows服務啓動瀏覽器

但是,我有一種緊急情況,我必須快速找到解決方法。我需要我的Windows服務以某種方式打開帶有URL的瀏覽器(任何一種醜陋的黑客現在都會這樣做)。 答案狀態:

你需要寫一個單獨的代理應用程序,這將在用戶登錄時自動啓動,並與您的服務將溝通。然後代理可以啓動瀏覽器或做任何你需要的東西。

有人可以向我解釋我可以如何以一種簡單的方式做到這一點?該服務將如何與此「代理」進行對話?這個'代理'究竟是什麼?

任何鏈接或建議將不勝感激。

編輯:目前。我的服務嘗試運行下面的代碼:System.Diagnostics.Process.Start("www.google.com");

它,後來我發現,不工作

回答

4

沒有「快捷方式」來做到這一點,我很害怕。 (並且由於該服務無法與用戶的桌面交互,即使它可以啓動瀏覽器,用戶也無法看到它。)

您提到的「代理應用程序」是一個完全獨立的應用程序,它登錄時在用戶桌面下運行。它將不得不使用某種進程間通信方法(命名管道,TCP/IP等)來與服務進行通信。

服務不與桌面交互的原因是出於安全原因。沒有「快速解決方法」可用,並且不應該有一個。也沒有什麼「簡單的方法」來規避這種變化(並且不應該存在 - 如果你能以簡單的方式繞過安全性,那麼安全性就不高)。

+0

我有同樣的問題,但這種聯繫幫助我:HTTP://asprosys.blogspot .ro/2009/03/allow-service-to-interact-with-desktop.html – 2013-12-12 13:17:42

1

如果你需要緊急的東西 - 我會嘗試從服務中將消息放入MSMQ中,然後編寫一些簡單的客戶端來等待隊列消息,然後繼續處理它們。其實,如果你需要的東西很快 - 你甚至可以寫一些文件,並編寫簡單的桌面(winforms?)應用程序來讀取池中的文件(每5秒?),並打開瀏覽器在需要的時候。

+0

如果您的應用程序中沒有實現MSMQ,則MSMQ不是「快速」。 – 2013-03-24 06:40:22

+0

我確實喜歡寫入文件的想法。事實上,Windows服務是一個簡單的服務,只是保持輪詢URI的新更新(每5秒)。我可以替換服務本身並讓應用程序在後臺執行此操作嗎?這應該發生在一個線程?就像我說的,我是微軟技術新手 – 2013-03-24 06:49:13

+1

這取決於你想要完成什麼。如果你希望這種情況發生,用戶可以登錄,或不用 - 你有類似的服務。如果您僅在用戶登錄時需要此選項 - 是的,您可以從應用程序執行此操作。您可以使用Threading.Timer來安排操作。此外,您可能會發現「隱藏」您的申請表格(可能會留給托盤)。 – evgenyl 2013-03-24 06:59:10

4

是的,從一個服務,你可以在桌面上運行代碼......問題是在哪個桌面上?因爲可能有多個用戶同時登錄(例如,在Windows Server中可能有多個用戶遠程登錄)。

如果使用Process.Start從服務作爲你的例子:

System.Diagnostics.Process.Start("www.google.com"); 

該計劃將不會出現在任何用戶的桌面上,因爲服務不與任何用戶的桌面相關聯。


解決方案是檢測哪個用戶在本地登錄,然後以該用戶(以及該用戶的特權)執行該程序。爲此,我想鏈接你到another of my answers,我演示瞭如何從服務調用程序。 that answer我提出了這種技術所需的代碼

:這個答案是關於屏幕捕捉,還是我描述的技術是在用戶的會話調用程序,並且該方法從服務工作。所以它適用於你的問題。

您可以使用此方法直接執行所需的瀏覽器。作爲替代方案,您可以使用它來調用服務可執行文件,您可以在其中使用System.Environment.UserInteractive來檢測可執行文件是否不作爲服務運行。如果您將url作爲執行參數傳遞給您的服務可執行文件,那麼您可以使用默認瀏覽器使用Process.Start來打開它,就像上面的示例一樣。

:該代碼在Windows 7

2

使用shellexecute測試使用pinvoke http://www.pinvoke.net/default.aspx/shell32.shellexecute

C# Signature: 
public enum ShowCommands : int 
{ 
    SW_HIDE   = 0, 
    SW_SHOWNORMAL  = 1, 
    SW_NORMAL  = 1, 
    SW_SHOWMINIMIZED = 2, 
    SW_SHOWMAXIMIZED = 3, 
    SW_MAXIMIZE  = 3, 
    SW_SHOWNOACTIVATE = 4, 
    SW_SHOW   = 5, 
    SW_MINIMIZE  = 6, 
    SW_SHOWMINNOACTIVE = 7, 
    SW_SHOWNA  = 8, 
    SW_RESTORE  = 9, 
    SW_SHOWDEFAULT  = 10, 
    SW_FORCEMINIMIZE = 11, 
    SW_MAX   = 11 
} 

[DllImport("shell32.dll")] 
static extern IntPtr ShellExecute(
IntPtr hwnd, 
string lpOperation, 
string lpFile, 
string lpParameters, 
string lpDirectory, 
ShowCommands nShowCmd); 





// Asks default mail client to send an email to the specified address. 
    ShellExecute(IntPtr.Zero, "open", "mailto:[email protected]", "", "", ShowCommands.SW_SHOWNOACTIVATE ); 

    // Asks default browser to visit the specified site. 
    ShellExecute(IntPtr.Zero, "open", "http://channel9.msdn.com", "", "", ShowCommands.SW_SHOWNOACTIVATE); 

    // Opens default HTML editing app to allow for edit of specified file 
    ShellExecute(IntPtr.Zero, "edit", @"c:\file.html", "", "", ShowCommands.SW_SHOWNOACTIVATE); 
    //Modified by Aljaz: Replaced the last zero in these calls with 4 otherwise it wouldn't show anything 
    // 0 stands for SW_HIDE contant, which means execute but don't show the window which is probably not 
    // what we want. 
+0

這看起來很簡單。我很驚訝在我的快速研究中沒有遇到過這種情況。任何缺點或我缺少的東西?我會試一試 – 2013-03-24 06:53:18

+1

@AyrtonSenna「有什麼缺點」?是的:由於您使用的是服務,因此使用shellexecute調用的程序將不在用戶的桌面中,因此它將不可見。順便說一句,Proccess.Start相當於.NET中的shellexecute,這就是爲什麼在C#中使用shellexecute非常少見的原因。 – Theraot 2013-03-24 06:59:39