System.Drawing中在Windows或ASP.NET服务 [英] System.Drawing in Windows or ASP.NET services

查看:233
本文介绍了System.Drawing中在Windows或ASP.NET服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<据 MSDN 时,它是不给内使用类特别好的主意在 System.Drawing中命名空间中的Windows服务或ASP.NET服务。现在我开发类库可能需要访问这个特定的命名空间(用于测量字体),但它不能保证主机过程不是服务

现在有我退​​可以,如果Sy​​stem.Drawing中不可用一个不太理想的方法,但如果可能的话,我宁愿用类System.Drawing中。因此,我想要做的是确定runtume如果System.Drawing中的安全与否,如果是,则使用它,否则回落到次优的选择。

我的问题是:?我怎么可能发现,如果Sy​​stem.Drawing中安全使用

我想我应该为

  • 检测,如果当前进程是Windows服务或ASP.NET服务
  • 在检测如果GDI可用
  • 或者,也许有一种方法来问System.Drawing.dll程序本身是否安全使用

不幸的是,我不能想出一个方法来实现任何一种方法。没有人有任何想法?

解决方案

要消除混淆,System.Drawing中做的 ASP.NET和服务下工作的,它只是没有的支持。可以有高负荷(运行的非托管资源),内存或资源泄漏(不好实现,或者叫处置模式)和/或对话被弹出时,有没有桌面显示它们。问题

测试将采取后者的照顾和监督会提醒你前。但是,如果/当你有问题,不要指望能够调用PSS,并要求修复。

那么,你有什么选择呢?好吧,如果你并不需要一个完全支持的路线,你不要指望极端负载 - 很多人都忽视了MSDN警告和使用System.Drawing中取得成功。他们几个被咬伤,但还有很多比失败的故事更多的成功。

如果你想要的东西的支持,那么你需要知道你是否交互或者没有运行。就个人而言,我可能只是把它留给托管应用程序,以地方或其他设置非交互式标志。毕竟,应用程序是在最好的位置,以确定他们是否在托管环境中和/或想冒险的GDI +的问题。

但是,如果你要自动地检测您的环境中,我想有更糟糕的答案比提供的在这里的SO 获取的服务。总之,你可以检查EntryAssembly,看它是否从ServiceBase的继承,或尝试访问System.Console。对于ASP.NET,沿着相同的路线,检测HttpContext.Current应该足够了。

我的认为的存在会成为一个管理或P / Invoke的方式来寻找一个桌面(这实在是在这一切的决定性因素,我认为)和/或某事关AppDomain中这将您的线索。但我不知道它是什么,和MSDN小于启发就可以了。

编辑:拖钓MSDN,我记得它实际上是一个窗口站 (它承载桌面)这是最重要的一点在这里。有了这些信息,我能找到 GetProcessWindowStation()它返回一个处理当前窗口站。传递的句柄 GetUserObjectInformation()会得到你的USEROBJECTFLAGS 结构与应有的dwFlags与WSF_VISIBLE,如果你有一个可见的桌面。

另外, EnumWindowsStations 会给你电台列表,你可以检查 - WinSta0是互动的一个

不过,是的,我仍然认为只是有应用程序设置一个属性或东西是的的更容易的途径......

According to MSDN, it is not a particularly good idea to use classes within the System.Drawing namespace in a Windows Service or ASP.NET Service. Now I am developing a class library which might need to access this particular namespace (for measuring fonts) but it cannot be guaranteed that the host process is not a service.

Now there is a less optimal method I can fall back to if System.Drawing is unavailable, but if it is possible, I would rather use classes in System.Drawing. So what I would like to do is to determine at runtume if System.Drawing is safe or not, and if it is, use it, otherwise fall back to the suboptimal option.

My problem is: How could I possibly detect if System.Drawing is safe to use?

I think I should either

  • Detect if the current process is a Windows Service or ASP.NET service
  • Detect if GDI is available
  • Or maybe there is a way to ask System.Drawing.dll itself if it is safe to use

Unfortunately, I cannot come up with a way to implement any of these approaches. Does anyone have any idea?

解决方案

To clear up any confusion, System.Drawing does work under ASP.NET and Services, it's just not supported. There can be issues with high load (running out of unmanaged resources), memory or resource leaks (badly implemented or called dispose patterns) and/or dialogs being popped when there's no desktop to show them on.

Testing will take care of the latter, and monitoring will alert you to the former. But, if/when you have a problem, don't expect to be able to call PSS and ask for a fix.

So, what are you options? Well, if you don't need a completely supported route, and you don't expect extreme load - a lot of folks have disregarded the MSDN caveat and used System.Drawing with success. A few of them have been bitten, but there's alot more success than failure stories.

If you want something supported, then you need to know if you're running interactively or not. Personally, I'd probably just leave it up to the hosting app to set a non-interactive flag somewhere or other. After all, the app is in the best position to determine if they're in a hosted environment and/or want to risk the GDI+ issues.

But, if you want to automagically detect your environment, I suppose there's worse answers than are offered right here on SO for a service. To summarize, you can either check the EntryAssembly to see if it inherits from ServiceBase, or try to access System.Console. For ASP.NET, along the same lines, detecting HttpContext.Current should be sufficient.

I'd think there'd be a managed or p/invoke way to look for a desktop (which is really the defining factor in all this, I think) and/or something off the AppDomain which would clue you in. But I'm not sure what it is, and MSDN is less than enlightening on it.

Edit: Trolling MSDN, I recalled that it's actually a Window Station (which hosts a desktop) that's the important bit here. With that info, I was able to find GetProcessWindowStation() which returns a handle to the current window station. Passing that handle to GetUserObjectInformation() will get you a USEROBJECTFLAGS struct with should have a dwFlags with WSF_VISIBLE if you have a visible desktop.

Alternatively, EnumWindowsStations will give you a list of stations which you could check - WinSta0 is the interactive one.

But, yeah, I still think just having the app set a property or something is the much easier route....

这篇关于System.Drawing中在Windows或ASP.NET服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆