Element PNK-000 Конь-пилятор с бензопилой


Автор [info]rex_weblen@ljr

Он, кстати, еще переводит милый комикс Forest Hill, единственный, кстати, в рунете переводит, и поэтому не пропиарить просто не могу. А мне вот такого элемента (см. «Межлокальную контрабанду») сделал, по моему межлокальному эсхатологическому мутанту. За что ему почет и уважение. И знал бы он какую бурю породил в местном сообществе… Теперь у меня стадо коней-пиляторов, только отсканировать всех надо, рано или поздно покажу.

C#, Об анализе exceptions при вызове внешнего процесса.

Или отлавливаем нажатие клавиши «Отмена» в окне запроса UAC.

Вот однажды я писал небольшую утилиту, которая запускает любое приложение или командный файл (bat/cmd) от имени администратора. И мне в комментариях правильно намекнули, что я слишком грубо обрабатываю exceptions, которые могут случиться во время запуска внешнего процесса. Но вообще это хороший пример не только для конкретного случая, но и для подхода к обработке ошибок вообще. Кратко говоря — если вы предполагаете, что где-то может возникнуть ошибка, то есть два метода:
1. Предотвратить и обезвредить. К таким ошибкам, например, относится возможная недоступность файла для чтения/записи, или вообще его отсутствие, когда он нужен. Тогда лучше проверить, например, наличие файла, с помощью File.Exist() перед операцией с файлом.
2. Отловить на этапе времени выполнения. Для этого в C# существуют try/catch.

Нам нужен именно способ #2, поскольку мы не знаем и проверить заранее никак не можем, нажмет пользователь «Отмену» в окне запроса, или нет.

Изначально было сделано так, т.е. тут мы полагались на какой-то внутренний флаг, и от его состояния принимали решение, реагировать на ошибку или нет.

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

Немного теории об exceptions при запуске внешних процессов.

Как известно, в .NET ошибки времени выполнения распределены по классам. Есть общий класс — Exception, в который попадают все ошибки времени выполнения, и есть конкретные классы для обработки определенных ошибок. Иерархия обработки следующая: «от конкретных к общему». Т.е. сначала (если мы хотим их обработать), указываются конкретные ошибки, а потом можно, но не обязательно указать общий обработчик.
Конкретно при запуске внешних процессов могут возникнуть следующие виды ошибок:
ArgumentNullException
ObjectDisposedException
FileNotFoundException
(на самом деле в зависимости от OS но может не сработать, сработает следующий)
Win32Exception
он нам и нужен
PlatformNotSupportedException

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

Анализ Win32Exception

Для начала подключим нужный namespace:
using System.ComponentModel;

А теперь примемся за анализ. На самом деле, у каждой Win32-ошибки имеется внутренний код. В C#-exceptions он сохраняется в переменной NativeErrorCode. Т.е для решения нашей задачи, нам в конструкции try/catch достаточно отловить конкретный код ошибки. Для нажатия клавиши «Отмена» в окне UAC, это будет код 1223, «Операция отменена пользователем».

Исправление.

1. Сначала надо отловить ошибку типа Win32Exception и проанализировать значение NativeErrorCode.
2. Если NativeErrorCode == 1223, то не предпринимаем никаких действий.
3. Если NativeErrorCode другой, оповещаем пользователя об ошибке.
4. Если сработало исключение другого типа (не Win32Exception), то аналогично предыдущему пункту — оповещаем пользователя об ошибке.

//...

try
{
    Process.Start(psi);
}
catch (Win32Exception wex)
{
    if (wex.NativeErrorCode == 1223) //нажали "Отмену" в окне UAC
    {
        return true;
    }
    else //какой-то другой Win32 Error
    {
        ErrorMessage = wex.NativeErrorCode.ToString() + " " + wex.Message;
        return false;
    }
}
catch (Exception ex) //какой-то другой Exception
{
    ErrorMessage = ex.Message;
    return false;
}

//...

Код полностью здесь

Источники

1. Коды ошибок Win32 (Краткое пояснение и полный список кодов, англ., MSDN)
2. Нужный код ошибки (Отменено пользователем)

Утилита wsudo

1. Репозиторий на GitHub
2. Скачать
3. Заметка об утилите Копия

Про недавно разразившийся блокадосрач.

У меня отношение к истории примерно такое же, как у Невзорова, то есть, как к историям — в смысле баек и прочей литературщины. Меня тогда не было, сам не видел, так что именно байки, крипотные или прикольные, это уж в зависимости от содержания баек. Но про блокаду поведаю семейную историю. Какие-то родственники в блокаду попали, не буду говорить какие, да это не особо интересно, как мне, так и читателям.
Но прабабушке от них дошло последнее письмо. Понятно, что письмо наверняка было больше, и мне все это попало через перезказ, но одна фраза из рассказа, до сих пор не отпускает.
«Съели мы своего рыжего поросеночка».
У оставшихся в Ленинграде родственников был рыжий кот.

Пробрало хуже всякой крипоты.

На фильм я, естественно, не пойду (и даже в пиратке смотреть не буду), но другим никогда не буду запрещать . Запрещать запрещено. Если не будет запрещено запрещать, то «смогут повторить», а котов мне жалко.

Завелись попы.

Приснился забавный сон, будто в моей квартире завелись попы, маленькие такие, не больше спички ростом. Ходят крестными ходами (или чем там они должны ходить), реально, организованными кучками. Был даже патриарх, отличался от остальных попов, этой белой своей шапочкой-колпачком с миниатюрным крестиком сверху, как в телевизоре показывают. Ходил, естественно, впереди всех. Попы пели что-то свое церковное, и при этом издавали колокольный звон, причем, колокольни я не видел, то ли они издавали звон сверхъестественными способом, то ли колокольня была где-то заныкана, под тумбочку, например, или в стенной шкаф. Меня почему-то это умиляло, особенно звон и песнопения, да и просто было забавно. Я еще думал, что вот, травил клопов, а вместо клопов завелись попы.
Потом пришел участковый, стал ругаться, мол жалобы от соседей поступают на шум.
Я ему показал попов, сказал, что-то типа «Ну вот, завелись, сам не знаю что делать». Участковый как-то завис, причем завис именно как видео при плохой связи, судорожно подергиваясь и заикаясь, вроде даже квадратиками пошел.
А потом был уже другой сон, но не интересный, вроде про каких-то шпионов.