Content内容误删处理,Windows结构化异常处理浅析

2019-11-07 00:00 来源:未知

近期一直被一个问题所困扰,就是写出来的程序老是出现无故崩溃,有的地方自己知道可能有问题,但是有的地方又根本没办法知道有什么问题。更苦逼的事情是,我们的程序是需要7x24服务客户,虽然不需要实时精准零差错,但是总不能出现断线丢失数据状态。故刚好通过处理该问题,找到了一些解决方案,怎么捕获访问非法内存地址或者0除以一个数。从而就遇到了这个结构化异常处理,今就简单做个介绍认识下,方便大家遇到相关问题后,首先知道问题原因,再就是如何解决。废话不多说,下面进入正题。

图片 1图片 2

问题:在wsus content文件夹下误删除文件,需要重新下载文件
解决方法:
打开cmd
cd C:Program FilesUpdate ServicesTools
.wsusutil.exe reset
这时WSUS会下载所有已经审批但是不在WSUS Content文件加的更新

什么是结构化异常处理

结构化异常处理(structured exception handling,下文简称:SEH),是作为一种系统机制引入到操作系统中的,本身与语言无关。在我们自己的程序中使用SEH可以让我们集中精力开发关键功能,而把程序中所可能出现的异常进行统一的处理,使程序显得更加简洁且增加可读性。

使用SHE,并不意味着可以完全忽略代码中可能出现的错误,但是我们可以将软件工作流程和软件异常情况处理进行分开,先集中精力干重要且紧急的活,再来处理这个可能会遇到各种的错误的重要不紧急的问题(不紧急,但绝对重要)

当在程序中使用SEH时,就变成编译器相关的。其所造成的负担主要由编译程序来承担,例如编译程序会产生一些表(table)来支持SEH的数据结构,还会提供回调函数。

注:
不要混淆SHE和C++ 异常处理。C++ 异常处理再形式上表现为使用关键字catchthrow,这个SHE的形式不一样,再windows Visual C++中,是通过编译器和操作系统的SHE进行实现的。

在所有 Win32 操作系统提供的机制中,使用最广泛的未公开的机制恐怕就要数SHE了。一提到SHE,可能就会令人想起 *__try__finally* 和 *__except* 之类的词儿。SHE实际上包含两方面的功能:终止处理(termination handing)异常处理(exception handing)

  1 /*---------------------------------------------
  2 CHECKER4.C -- Mouse Hit-Test Demo Program No.4
  3               (c) Charles Petzold, 1998
  4 --------------------------------------------*/
  5 
  6 #include <Windows.h>
  7 
  8 #define DIVISIONS 5
  9 
 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 11 LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
 12 
 13 int idFocus = 0;
 14 TCHAR szChildClass[] = TEXT("Checker4_Child");
 15 
 16 int WINAPI WinMain( __in HINSTANCE hInstance
 17                     , __in_opt HINSTANCE hPrevInstance
 18                     , __in LPSTR lpCmdLine
 19                     , __in int nShowCmd )
 20 {
 21     static TCHAR szAppName[] = TEXT("Checker4");
 22     HWND hwnd;
 23     MSG msg;
 24     WNDCLASS wndclass;
 25 
 26     wndclass.style = CS_HREDRAW | CS_VREDRAW;
 27     wndclass.lpfnWndProc = WndProc;
 28     wndclass.cbClsExtra = 0;
 29     wndclass.cbWndExtra = 0;
 30     wndclass.hInstance = hInstance;
 31     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 32     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 33     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 34     wndclass.lpszMenuName = NULL;
 35     wndclass.lpszClassName = szAppName;
 36 
 37     if (!RegisterClass(&wndclass))
 38     {
 39         MessageBox(NULL, TEXT("Program requires Windows NT!")
 40             , szAppName, MB_ICONERROR);
 41         return 0;
 42     }
 43 
 44     wndclass.lpfnWndProc = ChildWndProc;
 45     wndclass.cbWndExtra = sizeof(long);
 46     wndclass.hIcon = NULL;
 47     wndclass.lpszClassName = szChildClass;
 48 
 49     RegisterClass(&wndclass);
 50 
 51     hwnd = CreateWindow(szAppName, TEXT("Checker4 Mouse Hit-Test Demo")
 52         , WS_OVERLAPPEDWINDOW
 53         , CW_USEDEFAULT, CW_USEDEFAULT
 54         , CW_USEDEFAULT, CW_USEDEFAULT
 55         , NULL, NULL, hInstance, NULL);
 56 
 57     ShowWindow(hwnd, nShowCmd);
 58     UpdateWindow(hwnd);
 59 
 60     while (GetMessage(&msg, NULL, 0, 0))
 61     {
 62         TranslateMessage(&msg);
 63         DispatchMessage(&msg);
 64     }
 65 
 66     return msg.wParam;
 67 }
 68 
 69 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 70 {
 71     static HWND hwndChild[DIVISIONS][DIVISIONS];
 72     int cxBlock, cyBlock, x, y;
 73 
 74     switch (message)
 75     {
 76     case WM_CREATE:
 77         for (x = 0; x != DIVISIONS; ++x)
 78             for (y = 0; y != DIVISIONS; ++y)
 79             {
 80                 hwndChild[x][y] = CreateWindow(szChildClass, NULL
 81                     , WS_CHILDWINDOW | WS_VISIBLE
 82                     , 0, 0, 0, 0
 83                     , hwnd, (HMENU)(y << 8 | x)
 84                     , (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
 85             }
 86         return 0;
 87 
 88     case WM_SIZE:
 89         cxBlock = LOWORD(lParam) / DIVISIONS;
 90         cyBlock = HIWORD(lParam) / DIVISIONS;
 91 
 92         for (x = 0; x != DIVISIONS; ++x)
 93             for (y = 0; y != DIVISIONS; ++y)
 94             {
 95                 MoveWindow(hwndChild[x][y]
 96                     , x * cxBlock, y * cyBlock
 97                     , cxBlock, cyBlock, TRUE);
 98             }
 99         return 0;
100 
101     case WM_LBUTTONDOWN:
102         MessageBeep(0);
103         return 0;
104 
105         //on set-focus message, set focus to child window
106     case WM_SETFOCUS:
107         SetFocus(GetDlgItem(hwnd, idFocus));
108         return 0;
109 
110         //on key-down message, possibly change the focus window
111     case WM_KEYDOWN:
112         x = idFocus & 0xff;
113         y = idFocus >> 8;
114 
115         switch (wParam)
116         {
117         case VK_UP:
118             --y;
119             break;
120 
121         case VK_DOWN:
122             ++y;
123             break;
124 
125         case VK_LEFT:
126             --x;
127             break;
128 
129         case VK_RIGHT:
130             ++x;
131             break;
132 
133         case VK_HOME:
134             x = y = 0;
135             break;
136 
137         case VK_END:
138             x = y = DIVISIONS - 1;
139             break;
140 
141         default:
142             return 0;
143         }
144 
145         x = (x + DIVISIONS) % DIVISIONS;
146         y = (y + DIVISIONS) % DIVISIONS;
147 
148         idFocus = y << 8 | x;
149         SetFocus(GetDlgItem(hwnd, idFocus));
150         return 0;
151 
152     case WM_DESTROY:
153         PostQuitMessage(0);
154         return 0;
155     }
156 
157     return DefWindowProc(hwnd, message, wParam, lParam);
158 }
159 
160 LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
161 {
162     HDC hdc;
163     PAINTSTRUCT ps;
164     RECT rect;
165 
166     switch (message)
167     {
168     case WM_CREATE:
169         SetWindowLong(hwnd, DWL_MSGRESULT, 0);    // on/off flag
170         return 0;
171 
172     case WM_KEYDOWN:
173         //send most key press to the parent window
174         if (wParam != VK_RETURN && wParam != VK_SPACE)
175         {
176             SendMessage(GetParent(hwnd), message, wParam, lParam);
177             return 0;
178         }
179 
180         //for Return and Space, fall through to toggle the square
181     case WM_LBUTTONDOWN:
182         SetWindowLong(hwnd, DWL_MSGRESULT, 1 ^ GetWindowLong(hwnd, DWL_MSGRESULT));
183         SetFocus(hwnd);
184         InvalidateRect(hwnd, &rect, FALSE);
185         return 0;
186 
187         //for focus message, invalidate the window for repaint
188     case WM_SETFOCUS:
189         idFocus = GetWindowLong(hwnd, GWL_ID);
190 
191         //fall through
192     case WM_KILLFOCUS:
193         InvalidateRect(hwnd, NULL, TRUE);
194         return 0;
195 
196     case WM_PAINT:
197         hdc = BeginPaint(hwnd, &ps);
198         
199         GetClientRect(hwnd, &rect);
200         Rectangle(hdc, 0, 0, rect.right, rect.bottom);
201 
202         //draw the "x" mark
203         if (GetWindowLong(hwnd, DWL_MSGRESULT))
204         {
205             MoveToEx(hdc, 0, 0, NULL);
206             LineTo(hdc, rect.right, rect.bottom);
207             MoveToEx(hdc, 0, rect.bottom, NULL);
208             LineTo(hdc, rect.right, 0);
209         }
210 
211         //draw the "focus" rectangle
212         if (hwnd == GetFocus())
213         {
214             rect.left += rect.right / 10;
215             rect.right -= rect.left;
216             rect.top += rect.bottom / 10;
217             rect.bottom -= rect.top;
218 
219             SelectObject(hdc, GetStockObject(NULL_BRUSH));
220             SelectObject(hdc, CreatePen(PS_DASH, 0, 0));
221             Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
222             DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
223         }
224 
225         EndPaint(hwnd, &ps);
226         return 0;
227     }
228 
229     return DefWindowProc(hwnd, message, wParam, lParam);
230 }

图片 3

终止处理

终止处理程序确保不管一个代码块(被保护代码)是如何退出的,另外一个代码块(终止处理程序)总是能被调用和执行,其语法如下:

__try
{
    //Guarded body
    //...
}
__finally
{
    //Terimnation handler
    //...
}

**__try __finally** 关键字标记了终止处理程序的两个部分。操作系统和编译器的协同工作保障了不管保护代码部分是如何退出的(无论是正常退出、还是异常退出)终止程序都会被调用,即**__finally**代码块都能执行。

CHECKER4.C

 wsusuilt命令官方解释:

TAG标签:
版权声明:本文由澳门金莎娱乐网站发布于澳门金莎娱乐网站,转载请注明出处:Content内容误删处理,Windows结构化异常处理浅析