Можно ли «обмануть» PrintScreen, заменить содержимое моей формы чем-то другим перед захватом? - PullRequest
5 голосов
/ 15 мая 2010

У меня есть проблемы.

В более ранней версии нашего продукта у нас было окно сообщения об ошибке (последнее средство, необработанное исключение), в котором отображалось сообщение об исключении, его тип, трассировка стека + различные биты и фрагменты информации.

Это окно было дружественным к экрану печати, так как если пользователь просто сделал захват экрана печати и отправил нам скриншот по электронной почте, у нас было почти все, что нужно для диагностики проблемы.

Тем не менее, форма была сочтена слишком технической и "страшной" для обычных пользователей, поэтому она была уменьшена до более дружественной, по-прежнему показывая сообщение об ошибке, но не трассировку стека и некоторые более кровавые детали, которые я все еще хотел бы получить. Кроме того, в форму были добавлены возможности отправлять нам по электронной почте текстовый файл, содержащий все, что у нас было раньше, + множество других технических деталей, в основном все, что нам нужно.

Однако пользователи по-прежнему используют PrintScreen для захвата содержимого формы и отправки по электронной почте нам, что означает, что у меня теперь меньше, чем оптимальный объем информации.

Так что мне было интересно. Могу ли я предварительно отрендерить растровое изображение того же размера, что и моя форма, со всем необходимым на нем, обнаружить, что PrintScreen был поражен, и быстро поменять содержимое формы с моим растровым изображением до захвата, а затем снова после этого?

И прежде чем вы скажете "просто обучать пользователей", да, это не сработает. Это не наши пользователи, а пользователи наших клиентов, поэтому мы не можем сказать им, что им нужно все это очень много.

Или, за исключением этого, есть ли способ для меня обнаружить PrintScreen, сказать Windows игнорировать его и вместо этого реагировать на него, выгружая вышеупомянутый предварительно обработанный растровый рисунок в буфер обмена, готовый для размещения в электронном письме?

Код - C # 3.0 в .NET 3.5, если это имеет значение, но указатели на что-то, на что можно посмотреть, достаточно хороши.

Наше окно сообщений об ошибках имеет следующие возможности:

  • Показать снимок экрана, который был сделан при возникновении ошибки (содержит все открытые окна программы на тот момент, до того, как отобразился диалог ошибки)
  • Показать текстовый файл, содержащий все кровавые детали, которые мы можем придумать (но без чувствительных вещей)
  • Сохраните два вышеупомянутых файла на диск для последующего прикрепления пользователем к электронному письму или еще чего-нибудь подобного
  • Отправка вышеупомянутых двух файлов нам по электронной почте, либо путем открытия нового обращения в службу поддержки, либо путем ввода номера существующего обращения в службу поддержки, чтобы добавить в него дополнительную информацию
  • Игнорировать проблему и надеяться, что она исчезнет (возврат в приложение)
  • Выход из приложения (в крайнем случае)

Мы все еще получаем скриншоты от некоторых пользователей. Не все, заметьте, поэтому мой вопрос заключается в том, как сделать так, чтобы кнопка PrintScreen еще больше помогла нам тем пользователям, которые все еще ее используют.

Ответы [ 5 ]

2 голосов
/ 16 мая 2010

Один вариант: поместите трассировку стека и другие страшные вещи в экран ошибок, используя маленький, малоконтрастный тип - например, темно-серый на светло-сером - так что пользователь на самом деле даже не видит его, но экран печати захватывает его.

Но если вы хотите обнаружить PrintScreen и делать свое дело, этот выглядит как пример того, что вы хотите.

1 голос
/ 16 мая 2010

Это в теории ... лучший способ справиться с этим, я думаю,

Теперь, когда вы перехватываете экран печати, вызывайте сообщение WM_PRINT, захватывая содержимое, которое вы хотите захватить.

Я знаю, что это кратко и кратко, но я надеюсь, что это должно помочь вам.

1 голос
/ 16 мая 2010

Не возможно ли вообще отключить кнопку Print Screen, когда всплывающее окно с ошибкой активно? Пусть он отобразит сообщение в виде «Пожалуйста, используйте отчетливо видимую кнопку в центре экрана, чтобы сообщить об ошибке». Я согласен, что это нарушает ожидаемую функциональность, но если ваши пользователи действительно настолько глупы, что вы можете сделать ...

В качестве альтернативы, он может автоматически сообщать об ошибках (или сохранять данные локально, чтобы их можно было извлечь позже, если вы не можете отправить их без объяснения причин), не спрашивая пользователя. Если вы хотите иметь возможность связать скриншоты с печатью с подробными данными об ошибках, попросите его отправить уникальный идентификатор с данными, которые также отображаются в углу всплывающего окна.

1 голос
/ 16 мая 2010

А как насчет того, чтобы предложить им кнопку «Print Screen», которая выполняет эти действия, а также выполняет печать экрана? Если вы заблокировали этот метод, чтобы ваши клиенты отправляли подробности об ошибках, это может быть более простой путь.

Поднято из моего комментария ниже для более легкой ссылки (возможно, выглядит полезным):

codeproject.com / KB / CS / PrintScreen.aspx

0 голосов
/ 18 декабря 2015

Единственное решение, которое я придумал, - предложить большие, большие, легко читаемые кнопки на панели инструментов, которые дают пользователю каждые возможность сохранять содержимое диалогового окна с ошибкой:

  • Сохранить
  • Копировать в буфер обмена
  • Отправить по электронной почте
  • Печать

И после всего этого я использую функцию Windows SetWindowDisplayAffinity , чтобы показать пользователю черный ящик, где форма должна быть:

Эта функция и GetWindowDisplayAffinity предназначены для поддержки функции защиты содержимого окна, которая является новой для Windows 7. Эта функция позволяет приложениям защищать свое собственное содержимое окна от захвата или копирования через определенный набор функции и API общедоступной операционной системы. Однако он работает только тогда, когда Desktop Window Manager (DWM) создает рабочий стол.

Важно отметить, что в отличие от функции безопасности или реализации управления цифровыми правами (DRM), нет гарантии, что при использовании SetWindowDisplayAffinity и GetWindowDisplayAffinity и других необходимых функций например, DwmIsCompositionEnabled , будет строго защищать оконный контент, например, когда кто-то делает снимок экрана.

Если на их скриншотах показан большой черный ящик, надеюсь, они поймут намек.

Я добавил поражение, если они удерживают нажатой клавишу Shift при нажатии «показать подробности ошибки» , я не добавляю защиту при построении формы:

//Code released into public domain. No attribution required.
if (!IsShiftKeyPressed())
   SetWindowDisplayAffinity(this.Handle, WDA_MONITOR); //Please don't screenshot the form, please e-mail me the contents!
...