//--------------------------------------------------------------------------- // createInstallFileMap //--------------------------------------------------------------------------- int CPluginDeploymentEngine::createInstallFileMap(IPropertyTree& node, const char* destPath, mmapStr2PairStrStr& fileMap) const { CDeploymentEngine::createInstallFileMap(node, destPath, fileMap); //get files for plugin references... // StringBuffer sPluginDest; getPluginDirectory(destPath, sPluginDest);//get absolute path where plugins are to be deployed //process plugin references for this eclserver process and add files for each service used by //each binding before adding files for this esp process Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef"); ForEach(*iter) { // Lookup plugin process const char* pluginName = iter->query().queryProp("@process"); IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName); if (!pluginProcess) throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName); // Get plugin file list from the plugin process CDeploymentEngine::createInstallFileMap(*pluginProcess, sPluginDest.str(), fileMap); } return fileMap.size(); }
//--------------------------------------------------------------------------- // getPlugins //--------------------------------------------------------------------------- void CPluginDeploymentEngine::getPlugins(StringArray& plugins, StringBuffer& sPluginsPath, const char* pluginDest) const { // Iterate through plugin references Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef"); ForEach(*iter) { // Lookup plugin process const char* pluginName = iter->query().queryProp("@process"); IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName); if (!pluginProcess) throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName); // Get plugin file list from the plugin process mmapStr2PairStrStr fileMap; CDeploymentEngine::createInstallFileMap(*pluginProcess, pluginDest, fileMap); mmapStr2PairStrStr::const_iterator i; mmapStr2PairStrStr::const_iterator iEnd = fileMap.end(); for (i=fileMap.begin(); i != iEnd; i++) { const char* dest = (*i).first.c_str(); const char* ext = ::PathFindExtension(dest); // Append plugin to files list - only care about dll/so if (ext && (stricmp(ext, ".dll")==0 || stricmp(ext, ".so")==0) && plugins.find(dest) == NotFound) { plugins.append(dest); sPluginsPath.append(dest).append(';'); } } } }
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR cmdLine, int) { // Parse command line options char *targetExe = strtok(cmdLine, " "); char *trayIconFile = strtok(NULL, " "); if (!targetExe || !trayIconFile) { MessageBox(NULL, "KillApp: Monitor a Windows program via a tray icon,\n" "and provide a right-click menu to forcefully terminate it.\n" "http://github.com/adam-nielsen/killapp\n\n" "Usage: killapp target.exe trayicon.ico", "Error", MB_OK | MB_ICONERROR); return 1; } // Load PSAPI.DLL and get the functions we need HMODULE hPS = LoadLibrary("PSAPI.DLL"); if (hPS == NULL) { showSystemError("Unable to load PSAPI.DLL: %1"); return 1; } EnumProcesses = (FN_ENUMPROC)GetProcAddress(hPS, "EnumProcesses"); if (EnumProcesses == NULL) { showSystemError("EnumProcesses() not found in PSAPI.DLL: %1"); return 1; } GetProcessImageFileName = (FN_GETPROCFN)GetProcAddress(hPS, "GetProcessImageFileNameA"); if (GetProcessImageFileName == NULL) { showSystemError("GetProcessImageFileName() not found in PSAPI.DLL: %1"); return 1; } // Load the icon we'll be using in the system tray HICON hTrayIcon = (HICON)LoadImage(NULL, trayIconFile, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE); if (hTrayIcon == NULL) { showSystemError("Couldn't load icon file \"%%s\": %1", trayIconFile); } // Try for five seconds to find the process. If it doesn't appear after this // time we assume it exited/crashed and exit ourselves. int waited = 0; while (((::hApp = lookupProcess(targetExe)) == NULL) && (waited < WAIT_SECS)) { Sleep(1000); waited++; } if (::hApp == NULL) return 2; // Create a window to receive messages from the tray icon WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = windowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = WINDOW_CLASS; ATOM aWndClass = RegisterClass(&wc); if (aWndClass == 0) { showSystemError("Could not register window class: %1"); return 1; } HWND hWndHidden = CreateWindowEx( WS_EX_TOOLWINDOW, WINDOW_CLASS, "KillApp", 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, 0 ); // Create a thread to wait until the app exits HANDLE hQuitEvent = CreateEvent(NULL, TRUE, FALSE, QUIT_EVENT_NAME); if (hQuitEvent == NULL) { showSystemError("Could not create quit event: %1"); return 3; } DWORD threadId; THREAD_DATA threadData; threadData.hApp = ::hApp; threadData.hWndNotify = hWndHidden; threadData.hQuitEvent = hQuitEvent; HANDLE hThread = CreateThread(NULL, 0, waitThread, (LPVOID)&threadData, 0, &threadId); if (hThread == NULL) { showSystemError("Cannot create monitoring thread: %1"); return 3; } // Add a tray icon NOTIFYICONDATA trayIcon; trayIcon.cbSize = sizeof(NOTIFYICONDATA); trayIcon.hWnd = hWndHidden; trayIcon.uID = 0; trayIcon.uFlags = NIF_MESSAGE | NIF_ICON; trayIcon.uCallbackMessage = TRAY_MSG; trayIcon.hIcon = hTrayIcon; trayIcon.szTip[0] = 0; if (!Shell_NotifyIcon(NIM_ADD, &trayIcon)) { MessageBox(NULL, "Unable to add tray icon.", "Error", MB_OK | MB_ICONERROR); return 3; } MSG msg; while (GetMessage(&msg, hWndHidden, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } // Signal the quit event and wait for up to two seconds for the thread to // terminate. SignalObjectAndWait(hQuitEvent, hThread, 2000, FALSE); // Clean up CloseHandle(hThread); CloseHandle(hQuitEvent); Shell_NotifyIcon(NIM_DELETE, &trayIcon); DestroyWindow(hWndHidden); UnregisterClass(WINDOW_CLASS, hInst); if (hTrayIcon) DestroyIcon(hTrayIcon); CloseHandle(::hApp); return 0; }