System.Drawing in Windows or ASP.NET Services

System.Drawing in Windows or ASP.NET services

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....

Edit again: 7 years later, I get clued into Environment.UserInteractive where MS does the exact GetProcessWindowStation dance I described above for you....I'd still recommend delegating to the hosting app (they may well want the faster, but slightly riskier System.Drawing path), but UserInteractive seems a good default to have without having it pinvoke it yourself.

How to access System.Drawing ie System.Drawing.Common in Asp.Net Core 3

System.Drawing utilizes Windows-specific APIs, and as such, is incompatible with .NET Core, which is cross-platform. Microsoft created System.Drawing.Common as an in-place replacement for System.Drawing for .NET Core. It is an exact API replacement, but performs the image operations in a cross-platform, rather than Windows-specific, way.

Long and short, yes, you just drop the NuGet into your project and go to town. There's nothing else you need to worry about.

Alternatives to System.Drawing for use with ASP.NET?

There is an excellent blog post including C# code about using the ImageMagick graphics library through Interop over at TopTen Software Blog. This post deals specifically with running ASP.net on linux under mono; however, the C# code should be perfectly copy-paste-able, the only thing you'll need to change is the Interop attributes if you are running under windows referencing a window binary (DLL).

ImageMagick® is a software suite to create, edit, compose, or convert
bitmap images. It can read and write images in a variety of formats
(over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD,
PNG, Postscript, SVG, and TIFF. Use ImageMagick to resize, flip,
mirror, rotate, distort, shear and transform images, adjust image
colors, apply various special effects, or draw text, lines, polygons,
ellipses and Bézier curves.

There is also an ImageMagick .Net development project on codeplex that wraps up everything for you. But it doesn't show active development since 2009, so it may be lagging behind the current ImageMagick library version. For a small trivial resizing routine, I'd probably stick with the interop. You just need to watch your implementation carefully for your own memory leak or unreleased resources (the library itself is well tested and vetted by the community).

The library is free and open source. The Apache 2 license appears to be compatible with both personal and commercial purposes. See ImageMagick License Page.

The library is totally cross platform and implements many powerful image handling and transformation routines that are not found in GDI+ (or not implemented under mono) and has a good reputation as an alternative for ASP.net image processing.

Update: Looks like there is an updated version of a .NET wrapper here: http://magick.codeplex.com/

how to draw in asp.net(c#)?

Use the different classes in the System.Drawing namespace.

Alternatively, use one of the many drawing libraries around.


Note:

The documentation on MSDN gives the following warning:

Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions. For a supported alternative, see Windows Imaging Components.

However, I and others who have done so have not found problems. Even MSDN magazine suggests it...

.NET Core and System.Drawing

System.Drawing is not a good option with ASP.NET

If you want graphics manipulation i suggest to use ImageSharp (https://github.com/JimBobSquarePants/ImageSharp) on .Net Core or ImageProcessor (http://imageprocessor.org/) / ImageResizer (https://imageresizing.net/) on .Net Framework

Also, if you really need to use System.Drawing change frameworks in your project.json to netstandard1.6 and add in dependencies "NETStandard.Library": "1.6.1"

What does this ominous System.Drawing warning mean?

That statement means any ASP.NET applications, including WebForms, MVC, Web API and SignalR.

System.Drawing was only designed for WinForms or console applications that run in a normal user session.

Somebody else might claim that System.Drawing works for them in those not-supported scenarios, but simply that's not supported by Microsoft at all.



Related Topics



Leave a reply



Submit