//---------------------------------------------------------------------------
// 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(';');
         }
       }
   }
}
Example #3
0
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;
}