Чтобы устранить путаницу, System.Drawing работает в ASP.NET и службах, просто не поддерживается . Могут возникнуть проблемы с высокой нагрузкой (из-за неуправляемых ресурсов), утечками памяти или ресурсов (плохо реализованными или вызванными шаблонами утилизации) и / или появлением диалоговых окон, когда нет рабочего стола, на котором они отображаются.
Тестирование позаботится о последнем, а мониторинг предупредит вас о первом. Но, если / когда у вас возникнут проблемы, не ожидайте, что сможете позвонить в PSS и попросить исправить ситуацию.
Итак, какие у вас варианты? Что ж, если вам не нужен полностью поддерживаемый маршрут, и вы не ожидаете экстремальной нагрузки - многие люди проигнорировали предупреждение MSDN и успешно использовали System.Drawing. Некоторые из них были укушены, но успеха гораздо больше, чем историй неудач.
Если вы хотите что-то поддерживать, вам нужно знать, работает ли он в интерактивном режиме или нет. Лично я, вероятно, просто оставлю это на усмотрение хостинг-приложения, чтобы установить неинтерактивный флаг где-либо. В конце концов, приложение находится в лучшем положении, чтобы определить, находятся ли они в размещенной среде и / или хотят рисковать проблемами GDI +.
Но, если вы хотите автоматически определять вашу среду, я полагаю, что есть худшие ответы, чем предлагаются здесь, на SO для службы. Подводя итог, вы можете либо проверить EntryAssembly, чтобы увидеть, если он наследует от ServiceBase, либо попытаться получить доступ к System.Console. Для ASP.NET, в том же духе, достаточно обнаружения HttpContext.Current.
Я бы подумал был бы управляемый или p / invoke способ поиска рабочего стола (который, я думаю, действительно является определяющим фактором во всем этом) и / или что-то вне AppDomain который подскажет вам. Но я не уверен, что это такое, и MSDN не слишком хорошо освещает это.
Редактировать: Троллинг MSDN, я вспомнил, что это на самом деле Window Station (которая содержит рабочий стол), это важный бит здесь. С помощью этой информации я смог найти GetProcessWindowStation () , который возвращает дескриптор текущей оконной станции. Передав этот дескриптор GetUserObjectInformation () , вы получите структуру USEROBJECTFLAGS с dwFlags с WSF_VISIBLE, если у вас есть видимый рабочий стол.
В качестве альтернативы, EnumWindowsStations предоставит вам список станций, которые вы можете проверить - WinSta0 является интерактивной.
Но, да, я все еще думаю, что просто установить в приложении свойство или что-то еще - это намного более простой маршрут ....
Снова отредактируйте: через 7 лет я узнаю о Environment.UserInteractive , где MS исполняет танец GetProcessWindowStation , который я описал выше для вас ... Я все равно рекомендую делегирование хост-приложению (оно может хотеть более быстрого, но немного более рискованного пути System.Drawing), но UserInteractive, по-видимому, является хорошим вариантом по умолчанию, если его не вводить самостоятельно.