Прихващане на ShellExecuteEx в
Дискутирайте във форума
Закачане на ShellExecuteEx в .NET |
ShellExtension.zip (88,48 Kb) |
Тази статия ще опише метод за внедряване на интерфейса IShellExecuteHook с цел прихващане на повиквания към функцията ShellExecuteEx, използвана от обвивката на Windows. Това ще ви позволи да напишете най-простото разширение на обвивката на Windows
Тази статия ще опише метод за внедряване на интерфейса IShellExecuteHook с цел прихващане на повиквания към функцията ShellExecuteEx, използвана от обвивката на Windows. Това ще ви позволи да напишете просто разширение на обвивката на Windows (за повече информация относно разширенията на обвивката и писането на разширения с Visual C++ и библиотеката ATL вижте статиите на Michael Dunn).
Създаване на COM компонент
За да създаде COM компонент, програмистът не трябва да полага допълнителни усилия и да пише допълнителен код, достатъчно е да зададе стойността на Register for COM Interop на True в свойствата на Build на проекта във Visual Studio .NET.
Интерфейс IShellExecuteHook
Интерфейсът IShellExecuteHook описва функциите ShellExecute и ShellExecuteEx, използвани от обвивката на Windows. Например, когато потребителят въведе команда с помощта на елемента от менюто "Изпълни" в менюто "Старт" или когато щракнете двукратно върху файл. По този начин, чрез прихващане на извикване на функция, можем да получим името на файл, директория или параметри на командния ред и да извършим някакво действие или да принудим обвивката да не прави нищо.
Интерфейсът е описан в заглавния файл shlobj.h, включен в SDK на платформата.
Помислете за функцията Execute:
Функцията връща S_OK, ако обвивката не трябва да предава обекта за по-нататъшна обработка (тази стойност може да се използва за информиранеобвивка, че разширението е обработило обекта, или ако не е желана допълнителна обработка) или S_FALSE в противен случай.
Аргументът pei е структура SHELLEXECUTEINFO, съдържаща информация за обекта, който се извиква. Разглеждайки заглавния файл shellapi.h, ще намерим описание на тази структура:
За пълнота ще дам описание на аргументите:
Внедряване в C#
Надявам се, че не сте се отегчили от описанието на C++ структурите. Вие чакахте .NET. Тук зачакахме. Сега ще "преведем" горните C++ описания в описания на .NET структури и методи. Освен това, както е описано по-долу, можете да внедрите всеки интерфейс.
Първо имаме нужда от GUID на интерфейса, който искаме да внедрим. След това ще влезем в заглавния файл ShlGuid.h, включен в SDK на платформата, и ще намерим реда:
В по-позната и позната форма: . Нуждаем се от тази стойност, за да импортираме COM интерфейса в C#:
Тъй като IShellExecuteHook наследява IUnknown, ние указваме COM типа на интерфейса InterfaceIsIUnknown. Атрибутът PreserveSig() е посочен така, че върнатият параметър се счита точно за параметър от стандартния тип HRESULT и не претърпява никакви трансформации.
След това описваме нашия COM клас, за това се нуждаем от уникален GUID, който може да бъде получен с помощта на стандартната помощна програма, включена в дистрибуцията на Visual Studio .NET - Създаване на GUID.
След като получим GUID, ще опишем класа, който ще бъде достъпен като COM:
Този клас трябва да съдържа само един метод Execute, чиято реализация има само една сложност - необходимо е да се преведе структурата SHELLEXECUTEINFO от C ++ в C # и да се прехвърлят неуправлявани типове към управлявани. За да могат членовете на структурата да бъдат разположени в паметта вред, трябва да посочите атрибута [StructLayout(LayoutKind.Sequential)]. Ето типовете и описание на структурата:
Обърнете внимание, че за да съпоставите управлявана структура с неуправляема, трябва изрично да посочите, че низовете трябва да бъдат предавани като неуправляеми, като използвате атрибута MarshalAs(UnmanagedType.LPWStr).
Последното нещо, което остава, е да се дефинират типовете връщани стойности, така че кодът за изпълнение на функцията да прилича още повече на стандартния код на COM класа. В нашия случай има само два вида връщани стойности S_OK и S_FALSE, ние ще ги опишем директно в класа:
Нека напишем кода за функцията Execute:
Основното нещо, когато прилагате тази функция, е да не забравяте да върнете стойността S_FALSE в случаите, когато обработката не е необходима. Като малък експеримент можете да опитате да върнете S_OK в началото на функцията. След това няма да можете да принудите обвивката да изпълни което и да е приложение или команда, без да премахнете манипулатора. Бъди внимателен!
Регистрация на "прехващач"
За да инсталирате нашия COM компонент, който прихваща функцията ShellExecuteEx, трябва да регистрирате самия компонент (както обикновено) и също така да посочите неговия GUID в клона на регистъра, предназначен за регистриране на компоненти:
За да направим това, ще създадем проста помощна програма за регистрация, която ще регистрира и изтрива регистрационни данни от регистъра. Ето двата метода, използвани за прилагане на тази функционалност:
За да започнете, отворете изходния код, който придружава тази статия, след това изградете решението и използвайте помощната програма за регистрация, за да регистрирате нашето най-просто разширение на обвивката. Наслади се! Ето как изглежда помощната програма:
Ето как работи нашето разширение:
Опитайте просто да въведете командата за време, преди да инсталирате разширениетои след инсталиране на разширението. Разликата е очевидна.
Заключение
Тази статия обсъди как да прихванете функцията ShellExecuteEx, както и как да преведете описанието на методите и структурите от C ++ на C #, както и да внедрите стандартния интерфейс във вашия собствен COM компонент.