📄 svcproc.cxx
字号:
PTextFile pidFile( argPID );
pidFile.SetLength(0);
pidFile << GetProcessID();
}
}
}
debugMode = (arguments.GetCount() > 0 && strcasecmp(arguments[0], "Debug") == 0 ) || arguments.HasOption( 'D' ) || arguments.HasOption( 'd' );
BOOL showWindow = !arguments.HasOption( 'd' ) ;
currentLogLevel = debugMode ? PSystemLog::Info : PSystemLog::Warning;
if (!debugMode && arguments.GetCount() > 0) {
for (PINDEX a = 0; a < arguments.GetCount(); a++)
ProcessCommand(arguments[a]);
if (controlWindow == NULL || controlWindow == (HWND)-1)
return GetTerminationValue();
if (debugWindow != NULL && debugWindow != (HWND)-1) {
::SetLastError(0);
PError << "Close window or select another command from the Control menu.\n" << endl;
}
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) != 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return GetTerminationValue();
}
if (!debugMode && !isWin95) {
static SERVICE_TABLE_ENTRY dispatchTable[] = {
{ "", PServiceProcess::StaticMainEntry },
{ NULL, NULL }
};
dispatchTable[0].lpServiceName = (char *)(const char *)GetName();
if (StartServiceCtrlDispatcher(dispatchTable))
return GetTerminationValue();
PSystemLog::Output(PSystemLog::Fatal, "StartServiceCtrlDispatcher failed.");
MessageBox(NULL, "Not run as a service!", GetName(), MB_TASKMODAL);
return 1;
}
if( debugMode )
if( !CreateControlWindow(showWindow) )
return 1;
else if (!CreateControlWindow(debugMode))
return 1;
if (IsServiceRunning(this)) {
MessageBox(NULL, "Service already running", GetName(), MB_TASKMODAL);
return 3;
}
if (debugMode) {
::SetLastError(0);
PError << "Service simulation started for \"" << GetName() << "\" version " << GetVersion(TRUE) << "\n"
"Close window to terminate.\n" << endl;
}
terminationEvent = CreateEvent(NULL, TRUE, FALSE, GetName());
PAssertOS(terminationEvent != NULL);
threadHandle = (HANDLE)_beginthread(StaticThreadEntry, 0, this);
PAssertOS(threadHandle != (HANDLE)-1);
SetTerminationValue(0);
MSG msg;
msg.message = WM_QUIT+1; //Want somethingthat is not WM_QUIT
do {
switch (MsgWaitForMultipleObjects(1, &terminationEvent,
FALSE, INFINITE, QS_ALLINPUT)) {
case WAIT_OBJECT_0+1 :
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message != WM_QUIT) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
break;
default :
// This is a work around for '95 coming up with an erroneous error
if (::GetLastError() == ERROR_INVALID_HANDLE &&
WaitForSingleObject(terminationEvent, 0) == WAIT_TIMEOUT)
break;
// Else fall into next case
case WAIT_OBJECT_0 :
if (!debugMode || controlWindow == NULL)
msg.message = WM_QUIT;
else {
PError << "nService simulation stopped for \"" << GetName() << "\".\n\n"
"Close window to terminate.\n" << endl;
ResetEvent(terminationEvent);
}
}
} while (msg.message != WM_QUIT);
if (controlWindow != NULL)
DestroyWindow(controlWindow);
// Set thread ID for process to this thread
activeThreadMutex.Wait();
activeThreads.SetAt(threadId, NULL);
threadId = GetCurrentThreadId();
threadHandle = GetCurrentThread();
activeThreads.SetAt(threadId, this);
activeThreadMutex.Signal();
OnStop();
return GetTerminationValue();
}
enum {
ExitMenuID = 100,
HideMenuID,
ControlMenuID,
CopyMenuID,
CutMenuID,
DeleteMenuID,
SelectAllMenuID,
#if PMEMORY_CHECK
MarkMenuID,
DumpMenuID,
StatsMenuID,
ValidateMenuID,
#endif
OutputToMenuID,
WindowOutputMenuID,
SvcCmdBaseMenuID = 1000,
LogLevelBaseMenuID = 2000
};
static const char ServiceSimulationSectionName[] = "Service Simulation Parameters";
static const char WindowLeftKey[] = "Window Left";
static const char WindowTopKey[] = "Window Top";
static const char WindowRightKey[] = "Window Right";
static const char WindowBottomKey[] = "Window Bottom";
static const char SystemLogFileNameKey[] = "System Log File Name";
BOOL PServiceProcess::CreateControlWindow(BOOL createDebugWindow)
{
if (controlWindow != NULL)
return TRUE;
WNDCLASS wclass;
wclass.style = CS_HREDRAW|CS_VREDRAW;
wclass.lpfnWndProc = (WNDPROC)StaticWndProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ICON_RESID));
wclass.hCursor = NULL;
wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = GetName();
if (RegisterClass(&wclass) == 0)
return FALSE;
HMENU menubar = CreateMenu();
HMENU menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING, OutputToMenuID, "&Output To...");
AppendMenu(menu, MF_STRING, WindowOutputMenuID, "&Output To Window");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
AppendMenu(menu, MF_STRING, ControlMenuID, "&Control");
AppendMenu(menu, MF_STRING, HideMenuID, "&Hide");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdVersion, "&Version");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
#if PMEMORY_CHECK
AppendMenu(menu, MF_STRING, MarkMenuID, "&Mark Memory");
AppendMenu(menu, MF_STRING, DumpMenuID, "&Dump Memory");
AppendMenu(menu, MF_STRING, StatsMenuID, "&Statistics");
AppendMenu(menu, MF_STRING, ValidateMenuID, "&Validate Heap");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
#endif
AppendMenu(menu, MF_STRING, ExitMenuID, "E&xit");
AppendMenu(menubar, MF_POPUP, (UINT)menu, "&File");
menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING, CopyMenuID, "&Copy");
AppendMenu(menu, MF_STRING, CutMenuID, "C&ut");
AppendMenu(menu, MF_STRING, DeleteMenuID, "&Delete");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
AppendMenu(menu, MF_STRING, SelectAllMenuID, "&Select All");
AppendMenu(menubar, MF_POPUP, (UINT)menu, "&Edit");
menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdInstall, "&Install");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdRemove, "&Remove");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdDeinstall, "&Deinstall");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdStart, "&Start");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdStop, "S&top");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdPause, "&Pause");
AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdResume, "R&esume");
AppendMenu(menubar, MF_POPUP, (UINT)menu, "&Control");
menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Fatal, "&Fatal Error");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Error, "&Error");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Warning, "&Warning");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Info, "&Information");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Debug, "&Debug");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Debug2, "Debug &2");
AppendMenu(menu, MF_STRING, LogLevelBaseMenuID+PSystemLog::Debug3, "Debug &3");
AppendMenu(menubar, MF_POPUP, (UINT)menu, "&Log Level");
if (CreateWindow(GetName(),
GetName(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
menubar,
hInstance,
NULL) == NULL)
return FALSE;
if (createDebugWindow && debugWindow == NULL) {
PConfig cfg(ServiceSimulationSectionName);
int l = cfg.GetInteger(WindowLeftKey, -1);
int t = cfg.GetInteger(WindowTopKey, -1);
int r = cfg.GetInteger(WindowRightKey, -1);
int b = cfg.GetInteger(WindowBottomKey, -1);
if (l > 0 && t > 0 && r > 0 && b > 0)
SetWindowPos(controlWindow, NULL, l, t, r-l, b-t, 0);
debugWindow = CreateWindow("edit",
"",
WS_CHILD|WS_HSCROLL|WS_VSCROLL|WS_VISIBLE|WS_BORDER|
ES_MULTILINE|ES_READONLY,
0, 0, 0, 0,
controlWindow,
(HMENU)10,
hInstance,
NULL);
SendMessage(debugWindow, EM_SETLIMITTEXT, isWin95 ? 32000 : 128000, 0);
DWORD TabStops[] = {
DATE_WIDTH,
DATE_WIDTH+THREAD_WIDTH,
DATE_WIDTH+THREAD_WIDTH+LEVEL_WIDTH,
DATE_WIDTH+THREAD_WIDTH+LEVEL_WIDTH+PROTO_WIDTH,
DATE_WIDTH+THREAD_WIDTH+LEVEL_WIDTH+PROTO_WIDTH+ACTION_WIDTH,
DATE_WIDTH+THREAD_WIDTH+LEVEL_WIDTH+PROTO_WIDTH+ACTION_WIDTH+32 // Standard tab width
};
SendMessage(debugWindow, EM_SETTABSTOPS, PARRAYSIZE(TabStops), (LPARAM)(LPDWORD)TabStops);
systemLogFileName = cfg.GetString(SystemLogFileNameKey);
if (!systemLogFileName) {
PFile::Remove(systemLogFileName);
DebugOutput("Sending all system log output to \"" + systemLogFileName + "\".\n");
}
}
return TRUE;
}
LPARAM WINAPI PServiceProcess::StaticWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Current().WndProc(hWnd, msg, wParam, lParam);
}
static void SaveWindowPosition(HWND hWnd)
{
RECT r;
GetWindowRect(hWnd, &r);
PConfig cfg(ServiceSimulationSectionName);
cfg.SetInteger(WindowLeftKey, r.left);
cfg.SetInteger(WindowTopKey, r.top);
cfg.SetInteger(WindowRightKey, r.right);
cfg.SetInteger(WindowBottomKey, r.bottom);
}
LPARAM PServiceProcess::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
#ifdef _DEBUG
static DWORD allocationNumber;
#endif
switch (msg) {
case WM_CREATE :
controlWindow = hWnd;
break;
case WM_DESTROY :
if (debugWindow == (HWND)-1) {
PNotifyIconData nid(hWnd, NIF_TIP);
nid.Delete(); // This removes the systray icon
}
controlWindow = debugWindow = NULL;
PostQuitMessage(0);
break;
case WM_ENDSESSION :
if (wParam && (debugMode || lParam != ENDSESSION_LOGOFF) && debugWindow != (HWND)-1)
OnStop();
return 0;
case WM_MOVE :
if (debugWindow != NULL)
SaveWindowPosition(hWnd);
break;
case WM_SIZE :
if (debugWindow != NULL && debugWindow != (HWND)-1) {
SaveWindowPosition(hWnd);
MoveWindow(debugWindow, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
}
break;
case WM_INITMENUPOPUP :
{
int enableItems = MF_BYCOMMAND|(debugMode ? MF_ENABLED : MF_GRAYED);
for (int i = PSystemLog::Fatal; i < PSystemLog::NumLogLevels; i++) {
CheckMenuItem((HMENU)wParam, LogLevelBaseMenuID+i, MF_BYCOMMAND|MF_UNCHECKED);
EnableMenuItem((HMENU)wParam, LogLevelBaseMenuID+i, enableItems);
}
CheckMenuItem((HMENU)wParam, LogLevelBaseMenuID+GetLogLevel(), MF_BYCOMMAND|MF_CHECKED);
enableItems = MF_BYCOMMAND|(debugMode ? MF_GRAYED : MF_ENABLED);
EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdStart, enableItems);
EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdStop, enableItems);
EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdPause, enableItems);
EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdResume, enableItems);
DWORD start, finish;
if (debugWindow != NULL && debugWindow != (HWND)-1)
SendMessage(debugWindow, EM_GETSEL, (WPARAM)&start, (LPARAM)&finish);
else
start = finish = 0;
enableItems = MF_BYCOMMAND|(start == finish ? MF_GRAYED : MF_ENABLED);
EnableMenuItem((HMENU)wParam, CopyMenuID, enableItems);
EnableMenuItem((HMENU)wParam, CutMenuID, enableItems);
EnableMenuItem((HMENU)wParam, DeleteMenuID, enableItems);
enableItems = MF_BYCOMMAND|(IsServiceRunning(this) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem((HMENU)wParam, ControlMenuID, enableItems);
break;
}
case WM_COMMAND :
switch (wParam) {
case ExitMenuID :
DestroyWindow(hWnd);
break;
case ControlMenuID :
if (IsServiceRunning(this))
OnControl();
break;
case HideMenuID :
ShowWindow(hWnd, SW_HIDE);
break;
#if PMEMORY_CHECK
case MarkMenuID :
allocationNumber = PMemoryHeap::GetAllocationRequest();
break;
case DumpMenuID :
PMemoryHeap::DumpObjectsSince(allocationNumber);
break;
case StatsMenuID :
PMemoryHeap::DumpStatistics();
break;
case ValidateMenuID :
PMemoryHeap::ValidateHeap();
break;
#endif
case CopyMenuID :
if (debugWindow != NULL && debugWindow != (HWND)-1)
SendMessage(debugWindow, WM_COPY, 0, 0);
break;
case CutMenuID :
if (debugWindow != NULL && debugWindow != (HWND)-1)
SendMessage(debugWindow, WM_CUT, 0, 0);
break;
case DeleteMenuID :
if (debugWindow != NULL && debugWindow != (HWND)-1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -