【问题标题】:Run a process/URI from IIS in a desktop session在桌面会话中从 IIS 运行进程/URI
【发布时间】:2014-05-20 16:37:57
【问题描述】:

我有一个在 IIS 中运行的 ASP.NET Web 应用程序。应用程序池和 Web 应用程序都设置为作为我创建的用户(不是 NETWORKSERVICE)运行。此用户拥有所有适当的权限(如伪管理员)。

应用程序使用磁铁 URI 调用 Process.Start()。网络服务器上安装了一个应用程序,它可以自动启动并开始处理磁铁 URI。如果我在网络服务器的“运行”框中输入磁铁 URI,一切都会按预期进行:应用程序启动并开始在后台处理 URI。如果我在 Visual Studio 中调试应用程序,也会发生同样的情况 - 它按预期工作,因为 IIS Express 实例也在同一个会话中运行。

但是,当我在 IIS 中从 Web 应用程序调用进程时,它不会引发任何异常或错误,但不会调用应用程序。我假设这是因为 IIS 在应用程序所在的不同会话中执行应用程序,因此应用程序无法响应 URI 调用,因此进程退出。

如何更改这行代码以在与桌面会话相同的上下文中运行,以便应用程序可以适当地响应和处理 URI?

Process.Start("magnet:?xt=urn:btih:0123456789ABCDEF");

如果桌面会话不存在(例如,该用户尚未登录服务器),我希望会引发某种可捕获的异常,以便在网站上显示友好的错误。

【问题讨论】:

  • 您可能会在事件日志中找到一些内容来解释发生了什么问题。从服务访问桌面的信息,类似问题,here
  • 因为这是一件有风险的事情(正如您可以想象的那样,并不是每个人都希望每个人都能够从 Web 客户端启动桌面应用程序......),因此设置起来可能非常困难。另外,您正在尝试调用与 Windows Shell 集成的东西(在磁铁 uri 后面),这增加了诊断的复杂性(通常,shell 通常会吃掉所有错误,以免打扰最终用户......)。首先要做的事情是:您可以使用 .exe 路径而不是 uri 启动应用程序吗?此处提供帮助:stackoverflow.com/questions/4679561/…
  • @SimonMourier 不,我已经尝试过了,该程序是专门为 not 设计的(我不知道为什么,但我已经阅读了它是不可能的)。
  • 好吧,您可以尝试使用其他桌面程序,例如记事本。这是第一步。

标签: c# asp.net iis process uri


【解决方案1】:

ASP.NET 网页和服务器控制代码在上下文中执行 Web 服务器上的 ASP.NET 工作进程。如果您使用开始 ASP.NET 网页或服务器控件中的方法,新进程 在具有受限权限的 Web 服务器上执行。过程 不会在与客户端浏览器相同的上下文中启动,并且不会 有权访问用户桌面。 http://msdn.microsoft.com/de-de/library/e8zac0ca.aspx

当您在 IIS 7+ 上使用 Process.Start 时,它会在 'Session 0' 中启动一个新进程作为服务,即使您将在服务器上使用相同的帐户登录,您也无法与该会话进行任何交互。但是,您可以在任务管理器中看到正在运行的进程(显示所有用户的进程)。

如果磁力链接没有关联,那么您可以将磁力链接作为参数传递

Process.Start("C:\...\Torrent.exe", "magnet:?...")

如果相关 exe 的进程根本没有启动 - 重定向其输出 (example) 并查看问题所在。

一般来说,从 Web 应用程序运行外部进程不是一个好主意,您可以考虑使用计划任务或 Windows 服务轮询公共存储库以查看是否应该运行批处理作业并从那里执行您的应用程序.

例子:

  1. 使用 aspx 将“magnet:?xt=...”写入文本文件 (c:\magnet.txt)
  2. 创建一个包含以下内容的 .bat 文件

    FOR /F %%x IN (c:\\magnet.txt) DO START %%x
    DEL /F c:\magnet.txt
    
  3. 创建一个打开 .bat 文件的计划任务,例如每分钟

完成!

【讨论】:

  • 我正在使用的应用程序不接受 URI 作为其进程的参数(它不会让您执行您发布的操作),我已经尝试过但没有成功。我喜欢存储请求并为它们轮询的想法......这是一个黑客,并没有直接回答问题,但如果没有解决这个问题,这是一个很好的“B计划”。
  • 您是否尝试重定向输出并检查进程是否在任务管理器中运行?
  • 应用程序已经在桌面会话上运行。启动 URI 应该“唤醒”应用程序并让它处理 URI。就像我说的,如果它在同一个会话中执行(比如通过 Windows 运行框),它会正常且正确地处理这一切,当应用程序存在于 IIS 中时就会出现问题。而且我不相信当你启动一个 URI 时会发生任何 stdio,因为它本身不是一个进程。
  • 正如我上面提到的,您无法与桌面会话进行通信。请参阅应该有帮助的 .bat 文件示例。
  • 这是我最终使用的方法,尽管我推荐 @Noseratio 的答案 here,因为 WCF 服务更可靠。我还选择了 Powershell 而不仅仅是一个批处理文件。
【解决方案2】:

您可以尝试在您的服务器上创建一个专用的普通用户帐户,然后使用

Process.Start(fileName, userName, password, domain)

在该用户凭据下启动您的进程。

另一个想法,创建一个自托管的 WCF 服务并在登录的桌面用户会话下运行它。 WCF 服务将启动您的“磁铁:”应用程序。从您的 ASP.NET 代码调用 WCF 服务(通过localhost)。

【讨论】:

    【解决方案3】:

    尝试使用 CreateProcessWithLogonW 代替 Process.Start()。 SO中回答的类似问题:Process.Start() under asp.net?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      相关资源
      最近更新 更多