Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003.
Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши. При наличии GUI эта проблема решается легко: эмулируем ввод с клавиатуры
byte VK_TAB = 0x09;
const int KEYEVENTF_KEYUP = 0x2;
const int KEYEVENTF_EXTENDEDKEY = 0x1;
user32.keybd_event(VK_TAB,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0);
user32.keybd_event(VK_TAB,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
Табом переходим до нужного места и «нажимаем ввод». так же есть топик http://rsdn.ru/Forum/?mid=948725
А при работе из под сервиса (автоматический запуск юнит тестов) или в залоченном компе этот метод не подходит – в window XP без наличия GUI сообщения система не пересылает.
Получаю кнопку Yes как IAccessible объект и вызываю метод accDoDefaultAction, но это не срабатывает (пока не выполнится условие описанное выше), также могу получить к примеру WndProc = GetClassLong(HWND, GCL_WNDPROC); а потом CallWindowProc(WndProc, HWND, WM_ACTIVATE, MA_ACTIVATE, 0); — но у этого метода пока не получилось работоспособность наладить
Если кто знает решение этой задачи или имеет соображения как это обойти просьба написать ответ, за ранее благодарен.
Re: Обход защиты Microsoft Office Outlook 2003 - окно "#3277
Здравствуйте, Vadimir, Вы писали:
V>Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003. V>Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши.
Так это ж диалог.
Узнай ID кнопки Yes и пошли окну BN_CLICKED через WM_COMMAND.
Re[2]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
Здравствуйте, EqWu, Вы писали:
EW>Здравствуйте, Vadimir, Вы писали:
V>>Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003. V>>Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши.
EW>Так это ж диалог. EW>Узнай ID кнопки Yes и пошли окну BN_CLICKED через WM_COMMAND.
Здравствуйте, EqWu, Вы писали: CallWindowProc(WndProc, HWND, WM_COMMAND, MAKEWPARAM(yesButtonID, BN_CLICKED), (LPARAM)yesButtonHWND);
ID кнопки Yes = 4774
У меня стоит Window XP я вдоволь наэксперементировался с CallWindowProc со следующим результатом:
Написал сабклассинг для своего окна все замечательно работает (код на C#)
IntPtr mWndProc = user32.GetWindowLong(mainhwnd, GWL_WNDPROC); /* возвращает к примеру -62989 а вот GetClassLong(mainhwnd, GCL_WNDPROC); -64345 хм*/
user32.WinProcDelegate winProcDelegate = new user32.WinProcDelegate(WinProc); /* public delegate int WinProcDelegate(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); */
IntPtr OldProc = user32.SetWindowLong(mainhwnd, GWL_WNDPROC, winProcDelegate); /* подменяю обработчик на свою функцию */
...
user32.SetWindowLong(mainhwnd, GWL_WNDPROC, OldProc); /* востановил обработчик */
private int WinProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam)
{
Console.WriteLine("hwnd " + hWnd.ToString()); /* вывожу для наглядности */
Console.WriteLine("Msg " + Msg.ToString());
Console.WriteLine("wParam " + wParam.ToString());
Console.WriteLine("lParam " + lParam.ToString());
user32.CallWindowProc(OldProc, hWnd, Msg, wParam, lParam); /* транслирую сообщение дальше в старый обработчик */
return 0;
}
Эта схема не работает для окон находящихся в другом процессе
GetWindowLong возвращает: 0 (NULL)
GetClassLong(HWnd, GCL_WNDPROC)возвращает: к примеру 2010572111 но из сказанного выше видно что это не тот указатель
соответственно вызвать CallWindowProc не получается
В поиске по мсдн нашел: << для SetWindowLong
GWL_WNDPROC Sets a new address for the window procedure.
Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread. >>
Я так понимаю что и для GetWindowLong будет справедливо ограничение: окно должно принадлежать томуже процессу что и вызывающий поток!?
Уточнение я немогу использовать sendmessage или keybd_event — они не работают при залоченной машине или когда идет запуск из сервиса с правами определенного пользователя (в Window XP только для локального сервиса можно разрешить работу с десктопом) вобщем я не хочу "городить огород" на сервере который управляется удаленно и держать его залогиненным под определенным пользователем....
Если есть идеи буду рад их прочесть, за ранее благодарен.
Re[4]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
Здравствуйте, Vadimir, Вы писали:
V>Уточнение я немогу использовать sendmessage или keybd_event — они не работают при залоченной машине или когда идет запуск из сервиса с правами определенного пользователя (в Window XP только для локального сервиса можно разрешить работу с десктопом) вобщем я не хочу "городить огород" на сервере который управляется удаленно и держать его залогиненным под определенным пользователем.... V>Если есть идеи буду рад их прочесть, за ранее благодарен.
А что мешает использовать PostMessage?
В крайнем случае можно внедрить DLL в процесс Outlook и там уже делать, что угодно.
Наконец, можно написать Add-in для Outlook или Exchange Client Extension (в этом случае, кстати, можно избежать появления тех самых "вредных" окон, но это — отдельная темя).
Если задачей является именно беспроблемное выполнение Unit-тестов, то Add-in, как мне кажется, самое оптимальное решение.
Он будет выполняться в контексте того же юзера, что и сам Outlook.
И еще вопрос: при работе тестов из-под сервиса как Outlook запускается? У него GUI то появляется вообще?
Re[5]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
Здравствуйте, EqWu, Вы писали:
EW>И еще вопрос: при работе тестов из-под сервиса как Outlook запускается? У него GUI то появляется вообще?
InfoPath (для тех кто не знает InfoPath входит в состав Microsoft Office 2003 и является довольно мощьным средством для сбора информации)
отправляет письма с помощью JavaScript
var outlookObject, outMail;
outlookObject = new ActiveXObject("Outlook.Application");
if (outlookObject == null)
{
Alert(GetText('CanNotCreateOutlookApplication'));
return;
}
outMail = outlookObject.CreateItem(0);
if (outMail == null)
{
Alert(GetText('CanNotCreateMail'));
return;
}
outMail.Recipients.Add(SendOptions['Recipients']);
outMail.Subject = SendOptions['Subject'];
outMail.Body = SendOptions['Body'];
outMail.Attachments.Add(filename);
outMail.Send;
Outlook при такой реализации показывает только окна защиты.
Я написал библиотеку для тестирования (еще сырая только обкатывается)
с помощью ее можно заполнять html формы в "Internet Explorer_Server" вызывать метод Click у тегов, так же получать и устанавливать проперти;
вызывать DefaultAction у элементов управления GUI — этого вполне хватает для GUI тестирования InfoPath form.
К примеру TestComplete довольно мощьное средсво для тестирования GUI, но на залоченной машине или из под сервиса — работать не будет.
Вот и изобретаю велосипед. Вобщем застрял только на Outlook-е.
Огромное спасибо за советы, буду дальше пробовать. (у меня еще есть 2-а дня если в них не уложусь то задача отложится на неопределенный срок)
Re: Обход защиты Microsoft Office Outlook 2003 - окно "#3277
Для тех кому интерестно
PostMessage действительно работает при залоченной машине (Win + L, для NT)
можно переместить фокусирование с кнопки "No" на кнопку "Yes" вот так
//C#
Замеченно если после появления окна защиты из другой программы запустить метод (нажать кнопку на форме) который
получет кнопку "Yes" как IAccessible объект и вызовет у нее метод accDoDefaultAction то она нажмется!
Следовательно они повесили хук (или ловят какие-то события по активированию/деактивированию)
Всего наилудшего. P.S. Если кто зает как этот тригер сбросить пишите.