Как подавить диалоговое окно, отображаемое кодом, которое я не могу изменить?

У меня есть COM-сервер Inproc от третьего лица. Одна из функций, которые я вызываю, отображает диалоговое окно с сообщением об ошибке, если оно ловушки определенного типа ошибки. Проблема в том, что я пытаюсь обрабатывать данные навалом, а источник данных, который я использую, вызывает появление диалогового windows с ошибкой. Это не было бы проблемой, если бы оно породило 1000 диалоговых окон, но вместо этого оно блокируется, и функция не возвращается, пока вы не нажмете OK.

введите описание изображения здесь

Как я могу отключить отображение диалога или программно нажать ОК?

Вот копия стека вызовов, так как она ждет меня, чтобы нажать ОК.

     [Управляется естественным переходом]  
 > System.Windows.Forms.dll! System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (System.IntPtr dwComponentID, int reason, int pvLoopData) Строка 2198 + 0x1e байты C #
     System.Windows.Forms.dll! System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (int reason, System.Windows.Forms.ApplicationContext context) Строка 3422 + 0x1b байтов C #
     System.Windows.Forms.dll! System.Windows.Forms.Application.ThreadContext.RunMessageLoop (int reason, System.Windows.Forms.ApplicationContext context) Строка 3306 + 0xc байты C #
     System.Windows.Forms.dll! System.Windows.Forms.Application.Run (System.Windows.Forms.Form mainForm) Строка 1495 + 0x31 байт C #
     UniversalDataImporter.exe! UniversalDataImporter.Program.Main () Строка 18 + 0x1d байтов C #
     Переход от управляемого к управляемому  
     [Управляется естественным переходом]  
     mscorlib.dll! System.AppDomain.ExecuteAssembly (строка assemblyFile, System.Security.Policy.Evidence assemblySecurity, строка [] args) Строка 2023 + 0x18 байт C #
     Microsoft.VisualStudio.HostingProcess.Utilities.dll! Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () + 0x27 байт  
     mscorlib.dll! System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта) Строка 68 + 0x27 байт C #
     mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executeContext, System.Threading.ContextCallback callback, состояние объекта, bool preserveSyncCtx) Строка 581 + 0xd байтов C #
     mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executeContext, System.Threading.ContextCallback callback, состояние объекта, bool preserveSyncCtx) Строка 530 + 0xd байтов C #
     mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executeContext, System.Threading.ContextCallback callback, состояние объекта) Строка 519 + 0xe байты C #
     mscorlib.dll! System.Threading.ThreadHelper.ThreadStart () Строка 105 + 0x20 байт C #
     Переход от управляемого к управляемому  

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

for (int i = 1; i <= recordCount; i++) { //If the dialog shows up the following line blocks till you press OK. var values = _comServer.GetValues(fileHandle, i); sqlDataConsumer.LoadRow(values); } 

В окне сообщения отображается цикл сообщений. Это то, что вы можете использовать, это позволяет вам вводить код с Control.BeginInvoke (), который запускается сразу же после появления windows сообщения. Затем вы можете использовать этот код, чтобы найти диалоговое окно и закрыть его. Добавьте новый class в свой проект и вставьте этот код:

 using System; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; public class DialogCloser : IDisposable { public DialogCloser() { if (Application.OpenForms.Count == 0) throw new InvalidOperationException(); Application.OpenForms[0].BeginInvoke(new Action(() => { // Enumerate windows to find dialogs if (cancelled) return; EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow); EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero); GC.KeepAlive(callback); })); } public void Dispose() { cancelled = true; } private static bool checkWindow(IntPtr hWnd, IntPtr lp) { // Checks if  is a Windows dialog StringBuilder sb = new StringBuilder(260); GetClassName(hWnd, sb, sb.Capacity); if (sb.ToString() == "#32770") { // Close it by sending WM_CLOSE to the window SendMessage(hWnd, 0x0010, IntPtr.Zero, IntPtr.Zero); } return true; } private bool cancelled; // P/Invoke declarations private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp); [DllImport("user32.dll")] private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp); [DllImport("kernel32.dll")] private static extern int GetCurrentThreadId(); [DllImport("user32.dll")] private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen); [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); } 

Использование образца:

 private void button1_Click(object sender, EventArgs e) { using (new DialogCloser()) { // Replace this with the call to the COM server method: MessageBox.Show("you never see this"); } } 

Прежде всего, было бы лучше, если бы сам COM-сервер мог быть превращен в режим, когда он не позволял вызывающему абоненту с нежелательным действием пользовательского интерфейса. При условии, что вы не можете изменить поведение сторонних компонентов, то, что вы все еще можете сделать, – это связать обработку сообщений и принудительное закрытие windows сообщения.

Перед выполнением вызова на стороннем сервере вы можете установить крючок сообщения с помощью SetWindowsHookEx и WH_CALLWNDPROC и ваш обратный вызов сможет отслеживать сообщения. В частности, вы сможете отправлять сообщения, подключать диалог WindowProc и т. Д. Включая, конечно, программное закрытие windows сообщения.

Interesting Posts

Как предотвратить обман системы в MS Office (и других приложениях)

Xcode 4 – ошибка «Недействительность подлинного подписи не найдена» при настройке профилей при установке нового Macintosh

Есть ли простой способ преобразования данных MySQL в Title Case?

Высокое потребление памяти с помощью Enumerable.Range?

Изменить переменную Struct в словаре

Выполнение динамического кросс-таблицы запроса

iTunes Connect API

Отключить хроматы Ctrl + P обработка печати

Уменьшить потребление энергии на компьютере

Как написать пользовательский десериализатор JSON для Gson?

Использование объектов Entity Framework как бизнес-объектов?

Как предотвратить мерцание в ListView при обновлении одного текста ListViewItem?

В чем смысл этой части кода? void (* signal (int sig, void (* func) (int))) (int);

Нельзя вывести соответствующий срок службы для autoref из-за противоречивых требований

Как исправить ошибки «Неверное строковое значение»?

Давайте будем гением компьютера.