为了消除任何混乱,System.Drawing 确实work在 ASP.NET 和服务下,它不是支持的。可能会出现高负载(耗尽非托管资源)、内存或资源泄漏(实施不当或称为处置模式)和/或在没有桌面显示对话框时弹出的问题。
测试将解决后者,而监控将提醒您注意前者。但是,如果/当您遇到问题时,不要指望能够致电 PSS 并请求修复。
那么,你有什么选择?好吧,如果您不需要完全支持的路线,并且您不期望极端负载 - 很多人都会无视 MSDN 警告并成功使用 System.Drawing。他们中的一些人被咬了,但成功的故事比失败的故事多得多。
如果您想要支持某些功能,那么您需要知道您是否正在交互运行。就我个人而言,我可能会将其留给托管应用程序在某处或其他地方设置非交互式标志。毕竟,应用程序最能确定它们是否处于托管环境中和/或想要冒 GDI+ 问题的风险。
但是,如果你想自动检测你的环境,我想有比提供的更糟糕的答案就在这儿 https://stackoverflow.com/questions/200163/am-i-running-as-a-service#200183为了一项服务。总而言之,您可以检查 EntryAssembly 以查看它是否继承自 ServiceBase,或者尝试访问 System.Console。对于 ASP.NET,同样,检测 HttpContext.Current 就足够了。
I'd think会有一种托管或 p/invoke 方式来查找桌面(我认为这实际上是所有这一切的决定因素)和/或 AppDomain 之外的东西,这会提示您。但我不确定什么确实如此,MSDN 对此缺乏启发。
编辑:浏览MSDN,我记得它实际上是一个窗口站 http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsAWindowStation.html(托管桌面)这是这里的重要一点。有了这些信息,我就能找到获取进程窗口站() http://msdn.microsoft.com/en-us/library/ms683225(VS.85).aspx它返回当前窗口站的句柄。将该句柄传递给获取用户对象信息() http://msdn.microsoft.com/en-us/library/ms683238(VS.85).aspx会给你一个用户对象标志 http://msdn.microsoft.com/en-us/library/ms686892(VS.85).aspx如果你有一个可见的桌面,struct with 应该有一个带有 WSF_VISIBLE 的 dwFlags 。
或者,枚举 Windows 站 http://msdn.microsoft.com/en-us/library/ms682644(VS.85).aspx将为您提供可以检查的电台列表 - WinSta0 是交互式电台。
但是,是的,我仍然认为只要让应用程序设置一个属性或其他东西就可以了much更方便的路线....
再次编辑:7年后,我发现了环境.用户交互 https://msdn.microsoft.com/en-us/library/system.environment.userinteractive(v=vs.110).aspx哪里 MSGetProcessWindowStation 是否准确跳舞 http://referencesource.microsoft.com/#mscorlib/system/environment.cs,7d2f1469d916fc63我在上面为您描述了......我仍然建议委托给托管应用程序(他们很可能want速度更快,但风险稍高的 System.Drawing 路径),但 UserInteractive 似乎是一个很好的默认设置,无需让它自己调用它。