EAccessVisualStudioResult AccessVisualStudioViaProcess(::DWORD& OutProcessID, FString& OutExecutablePath, const FString& InSolutionPath, const TArray<FVisualStudioSourceCodeAccessor::VisualStudioLocation>& InLocations) { OutProcessID = 0; EAccessVisualStudioResult AccessResult = EAccessVisualStudioResult::VSInstanceIsNotOpen; ::HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap != INVALID_HANDLE_VALUE) { MODULEENTRY32 ModuleEntry; ModuleEntry.dwSize = sizeof(MODULEENTRY32); PROCESSENTRY32 ProcEntry; ProcEntry.dwSize = sizeof(PROCESSENTRY32); // We enumerate the locations as the outer loop to ensure we find our preferred process type first // If we did this as the inner loop, then we'd get the first process that matched any location, even if it wasn't our preference for (const auto& Location : InLocations) { for (::BOOL bHasProcess = ::Process32First(hProcessSnap, &ProcEntry); bHasProcess && !OutProcessID; bHasProcess = ::Process32Next(hProcessSnap, &ProcEntry)) { ::HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcEntry.th32ProcessID); if (hModuleSnap != INVALID_HANDLE_VALUE) { if (::Module32First(hModuleSnap, &ModuleEntry)) { FString ProcPath = ModuleEntry.szExePath; FPaths::NormalizeDirectoryName(ProcPath); FPaths::CollapseRelativeDirectories(ProcPath); if (ProcPath == Location.ExecutablePath) { // Without DTE we can't accurately verify that the Visual Studio instance has the correct solution open, // however, if we've opened it (or it's opened the solution directly), then the solution path will // exist somewhere in the command line for the process FString CommandLine; if (GetProcessCommandLine(ProcEntry.th32ProcessID, CommandLine)) { FPaths::NormalizeFilename(CommandLine); if (CommandLine.Contains(InSolutionPath)) { OutProcessID = ProcEntry.th32ProcessID; OutExecutablePath = Location.ExecutablePath; AccessResult = EAccessVisualStudioResult::VSInstanceIsOpen; break; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access module information")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access module table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } ::CloseHandle(hModuleSnap); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access module table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } } } ::CloseHandle(hProcessSnap); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't access process table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } return AccessResult; }
BOOL GetProcessList() { HANDLE hProcessSnap; HANDLE hProcess; PROCESSENTRY32 pe32; DWORD dwPriorityClass; // Take a snapshot of all processes in the system. hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hProcessSnap == INVALID_HANDLE_VALUE ) { printError( TEXT("CreateToolhelp32Snapshot (of processes)") ); return( FALSE ); } // Set the size of the structure before using it. pe32.dwSize = sizeof( PROCESSENTRY32 ); // Retrieve information about the first process, // and exit if unsuccessful if( !Process32First( hProcessSnap, &pe32 ) ) { printError( TEXT("Process32First") ); // show cause of failure CloseHandle( hProcessSnap ); // clean the snapshot object return( FALSE ); } // Now walk the snapshot of processes, and // display information about each process in turn do { _tprintf( TEXT("\n\n=====================================================" )); _tprintf( TEXT("\nPROCESS NAME: %s"), pe32.szExeFile ); _tprintf( TEXT("\n-------------------------------------------------------" )); // Retrieve the priority class. dwPriorityClass = 0; hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID ); if( hProcess == NULL ) printError( TEXT("OpenProcess") ); else { dwPriorityClass = GetPriorityClass( hProcess ); if( !dwPriorityClass ) printError( TEXT("GetPriorityClass") ); CloseHandle( hProcess ); } _tprintf( TEXT("\n Process ID = 0x%08X"), pe32.th32ProcessID ); _tprintf( TEXT("\n Thread count = %d"), pe32.cntThreads ); _tprintf( TEXT("\n Parent process ID = 0x%08X"), pe32.th32ParentProcessID ); _tprintf( TEXT("\n Priority base = %d"), pe32.pcPriClassBase ); if( dwPriorityClass ) _tprintf( TEXT("\n Priority class = %d"), dwPriorityClass ); // List the modules and threads associated with this process ListProcessModules( pe32.th32ProcessID ); //ListProcessThreads( pe32.th32ProcessID ); GetProcessCommandLine(pe32.th32ProcessID); } while( Process32Next( hProcessSnap, &pe32 ) ); CloseHandle( hProcessSnap ); return( TRUE ); }
OSProcess * GetOSProcesses(DWORD *n, DWORD *exitTag, DWORD *lastErrorCode) { // Create toolhelp snapshot. HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(INVALID_HANDLE_VALUE == snapshot) { *exitTag = 1; return NULL; } PROCESSENTRY32W process; ZeroMemory(&process, sizeof(process)); process.dwSize = sizeof(process); DWORD i = 0; OSProcess *procs = malloc(sizeof(*procs) * 2048); if (NULL == procs) { *exitTag = 2; return NULL; } // Walkthrough a snapshot of all OS processes. if (Process32FirstW(snapshot, &process)) { do { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process.th32ProcessID); if (NULL == hProcess) { // Ignore the process. continue; } procs[i].PID = process.th32ProcessID; procs[i].PPID = process.th32ParentProcessID; procs[i].IsRemote = IsRemote(process.th32ProcessID, exitTag, lastErrorCode); if (0 != *exitTag) { CloseHandle(hProcess); *exitTag = 0; continue; } procs[i].ExecName = GetProcessNameInDeviceForm(hProcess, exitTag, lastErrorCode); if (0 != *exitTag) { CloseHandle(hProcess); *exitTag = 0; continue; } procs[i].CommandLine = GetProcessCommandLine(hProcess, exitTag, lastErrorCode); if (0 != *exitTag) { free(procs[i].ExecName); CloseHandle(hProcess); *exitTag = 0; continue; } procs[i].UProfile = GetProcessUserProfile(hProcess, exitTag); if (0 != *exitTag) { free(procs[i].ExecName); free(procs[i].CommandLine); FreeUserProfile(procs[i].UProfile); CloseHandle(hProcess); *exitTag = 0; continue; } CloseHandle(hProcess); // Increment index only if OSProccesEx has been filled correctly. ++i; } while (Process32NextW(snapshot, &process)); } else { // Could not retrieve information about the first process. *exitTag = 3; free(procs); procs = NULL; } CloseHandle(snapshot); *n = i; return procs; }