从Windows服务启动浏览器

本文关键字:浏览器 启动 服务 Windows | 更新日期: 2023-09-27 18:05:26

我对微软的世界有点陌生。我读了这个答案和其他很多链接,我意识到在Vista之后,windows服务不可能与桌面交互。

然而,我有一种紧急情况,我必须找到一个快速的解决方案。我需要我的windows服务以某种方式打开一个带有URL的浏览器(任何一种丑陋的黑客都可以做到)。答案是:

您需要编写一个单独的代理应用程序,该应用程序将在用户登录时自动启动,并与您的服务进行通信。然后代理可以启动浏览器或执行您需要的任何操作。

谁能告诉我怎么用简单的方法做这件事?该服务如何与这个"代理"对话?这个"代理"到底是什么?

任何链接或建议将非常感谢。

编辑:目前。我的服务试图运行以下代码:System.Diagnostics.Process.Start("www.google.com");

,我后来发现,它不工作

从Windows服务启动浏览器

是的,从一个服务你可以在桌面上运行代码…问题是在哪个桌面上?因为可能有不同的用户同时登录(例如,在Windows服务器中,可能有不同的用户远程登录)。

如果在您的示例中使用服务中的Process.Start:

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

程序不会出现在任何用户的桌面上,因为该服务没有与任何用户的桌面相关联。


解决方案是检测在本地登录的用户,然后以该用户的身份(并在该用户的权限下)执行程序。为此,我想将您链接到我的另一个答案,其中我演示了如何从服务调用程序。在那个答案中,我给出了该技术所需的代码

:该回答是关于屏幕捕获的,我描述的技术仍然是在用户会话中调用程序,该方法从服务中工作。所以它适用于你的问题。

您可以使用此方法直接执行所需的浏览器。作为替代方案,您可以使用它来调用服务可执行文件,其中可以使用System.Environment.UserInteractive来检测可执行文件是否没有作为服务运行。如果您将url作为执行参数传递给您的服务可执行文件,那么您可以使用默认浏览器使用Process.Start打开它,就像上面的示例一样。

注意:此代码在Windows 7上进行了测试。

恐怕没有"快速方法"可以做到这一点。(由于该服务不能与用户的桌面交互,即使它可以启动浏览器,用户也无法看到它。)

你提到的"代理应用程序"是一个完全独立的应用程序,它在用户登录时运行在用户的桌面下。它必须使用某种进程间通信方法(命名管道、TCP/IP等)与服务通信。

服务不与桌面交互的原因是出于安全考虑。没有"快速解决方案"可用,也不应该有。也没有"简单的方法"来规避这种更改(同样,也不应该有——如果您可以通过简单的方法绕过安全性,那么安全性就不高)。

use shellexecute using pinvokehttp://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:support@microsoft.com", "", "", 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.

如果你需要一些紧急的事情-我会尝试从服务中把消息放入MSMQ,并编写一些简单的客户端,等待队列消息,并进行它们。
更新:
实际上,如果你需要一些非常快的东西-你甚至可以写入一些文件,并编写简单的桌面(winforms?)应用程序来读取池中的文件(每5秒?),并在需要时打开浏览器。