/* Launches Minecraft and invokes mod injection */ HRESULT MinecraftAppLauncher::LaunchApplicationAndInjectMods(PDWORD processId_ptr, BOOL _doInject) { CComPtr<IApplicationActivationManager> spAppActivationManager; HRESULT result = E_INVALIDARG; /* Initialize IApplicationActivationManager */ result = CoCreateInstance(CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (LPVOID*)&spAppActivationManager); if (SUCCEEDED(result)) { /* This call ensures that the app is launched as the foreground window */ result = CoAllowSetForegroundWindow(spAppActivationManager, NULL); /* Launch the app */ if (SUCCEEDED(result)) { DWORD hInjectModsThreadId; HANDLE hInjectModsThread; /* Inject mods if activated */ if (_doInject) { /* Begin thread to find Minecraft and inject mods */ hInjectModsThread = CreateThread(0, 0, InjectMods_Threaded, NULL, NULL, &hInjectModsThreadId); /* Set thread priority to the highest priority to reduce the amount of context switching */ SetThreadPriority(hInjectModsThread, THREAD_PRIORITY_TIME_CRITICAL); } /* Initialize the application with mods */ result = spAppActivationManager->ActivateApplication(MINECRAFT_APP_NAME, NULL, AO_NONE, processId_ptr); } } return result; }
HRESULT AppUtils::LaunchApplication(LPCWSTR packageFullName, PDWORD pdwProcessId) { CComPtr<IApplicationActivationManager> spAppActivationManager; HRESULT result = E_INVALIDARG; /* Initialize IApplicationActivationManager */ result = CoCreateInstance(CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (LPVOID*)&spAppActivationManager); if (!SUCCEEDED(result)) return result; /* This call ensures that the app is launched as the foreground window */ result = CoAllowSetForegroundWindow(spAppActivationManager, NULL); /* Launch the app */ if (!SUCCEEDED(result)) return result; result = spAppActivationManager->ActivateApplication(packageFullName, NULL, AO_NONE, pdwProcessId); return result; }
bool System::OpenAppById( ) { HRESULT hr = S_OK; CComPtr<IApplicationActivationManager> aam = nullptr; hr = CoInitializeEx( nullptr, COINIT_APARTMENTTHREADED ); if( FAILED( hr ) ) { for( uint i = 0; i < 5; i++ ) { Sleep( 100 ); hr = CoInitializeEx( nullptr, COINIT_APARTMENTTHREADED ); if( SUCCEEDED( hr ) ) { break; } } assert( SUCCEEDED( hr ) ); } hr = CoCreateInstance( CLSID_ApplicationActivationManager, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS( &aam ) ); if( FAILED( hr ) ) { for( uint i = 0; i < 5; i++ ) { Sleep( 100 ); hr = CoCreateInstance( CLSID_ApplicationActivationManager, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS( &aam ) ); if( SUCCEEDED( hr ) ) { break; } } assert( SUCCEEDED( hr ) ); } hr = CoAllowSetForegroundWindow( aam, nullptr ); if( FAILED( hr ) ) { for( uint i = 0; i < 5; i++ ) { Sleep( 100 ); hr = CoAllowSetForegroundWindow( aam, nullptr ); if( SUCCEEDED( hr ) ) { break; } } assert( SUCCEEDED( hr ) ); } hr = aam->ActivateApplication( m_wsArgs[1].c_str(), nullptr, AO_NONE, &m_ulProcessId ); if( FAILED( hr ) ) { for( uint i = 0; i < 5; i++ ) { Sleep( 100 ); hr = aam->ActivateApplication( m_wsArgs[ 1 ].c_str( ), nullptr, AO_NONE, &m_ulProcessId ); if( SUCCEEDED( hr ) ) { return true; } } MessageBox( 0, L"Please double-check Application ID", L"ERROR: Application ID is probably not correct", MB_ICONERROR | MB_OK ); assert( SUCCEEDED( hr ) ); } return true; }
static int Launch() { Log(L"Launching browser..."); DWORD processID; // The interface that allows us to activate the browser CComPtr<IApplicationActivationManager> activateMgr; if (FAILED(CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (void**)&activateMgr))) { Fail(false, L"CoCreateInstance CLSID_ApplicationActivationManager failed."); return FAILURE; } HRESULT hr; WCHAR appModelID[256]; // Activation is based on the browser's registered app model id if (!GetDefaultBrowserAppModelID(appModelID, (sizeof(appModelID)/sizeof(WCHAR)))) { Fail(false, L"GetDefaultBrowserAppModelID failed."); return FAILURE; } Log(L"App model id='%s'", appModelID); // Hand off focus rights if the terminal has focus to the out-of-process // activation server (explorer.exe). Without this the metro interface // won't launch. hr = CoAllowSetForegroundWindow(activateMgr, nullptr); if (FAILED(hr)) { // Log but don't fail. This has happened on vms with certain terminals run by // QA during mozmill testing. Log(L"Windows focus rights hand off failed (HRESULT=0x%X). Ignoring.", hr); } Log(L"Harness process id: %d", GetCurrentProcessId()); // If provided, validate the firefox path passed in. int binLen = wcslen(kFirefoxExe); if (sFirefoxPath.GetLength() && sFirefoxPath.Right(binLen) != kFirefoxExe) { Log(L"firefoxpath is missing a valid bin name! Assuming '%s'.", kFirefoxExe); if (sFirefoxPath.Right(1) != L"\\") { sFirefoxPath += L"\\"; } sFirefoxPath += kFirefoxExe; } // Because we can't pass command line args, we store params in a // tests.ini file in dist/bin which the browser picks up on launch. CStringA testFilePath; if (sFirefoxPath.GetLength()) { // Use the firefoxpath passed to us by the test harness int index = sFirefoxPath.ReverseFind('\\'); if (index == -1) { Fail(false, L"Bad firefoxpath path"); return FAILURE; } testFilePath = sFirefoxPath.Mid(0, index); testFilePath += "\\"; testFilePath += kMetroTestFile; } else { // Use the module path char path[MAX_PATH]; if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) { Fail(false, L"GetModuleFileNameA errorno=%d", GetLastError()); return FAILURE; } char* slash = strrchr(path, '\\'); if (!slash) return FAILURE; *slash = '\0'; // no trailing slash testFilePath = path; testFilePath += "\\"; sFirefoxPath = testFilePath; sFirefoxPath += kFirefoxExe; testFilePath += kMetroTestFile; } // Make sure the firefox bin exists if (GetFileAttributesW(sFirefoxPath) == INVALID_FILE_ATTRIBUTES) { Fail(false, L"Invalid bin path: '%s'", sFirefoxPath); return FAILURE; } Log(L"Using bin path: '%s'", sFirefoxPath); Log(L"Writing out tests.ini to: '%s'", CStringW(testFilePath)); HANDLE hTestFile = CreateFileA(testFilePath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hTestFile == INVALID_HANDLE_VALUE) { Fail(false, L"CreateFileA errorno=%d", GetLastError()); return FAILURE; } DeleteTestFileHelper dtf(testFilePath); // nsAppRunner expects the first param to be the bin path, just like a // normal startup. So prepend our bin path to our param string we write. CStringA asciiParams = sFirefoxPath; asciiParams += " "; asciiParams += sAppParams; asciiParams.Trim(); Log(L"Browser command line args: '%s'", CString(asciiParams)); if (!WriteFile(hTestFile, asciiParams, asciiParams.GetLength(), nullptr, 0)) { CloseHandle(hTestFile); Fail(false, L"WriteFile errorno=%d", GetLastError()); return FAILURE; } FlushFileBuffers(hTestFile); CloseHandle(hTestFile); // Create a named stdout pipe for the browser if (!SetupTestOutputPipe()) { Fail(false, L"SetupTestOutputPipe failed (errno=%d)", GetLastError()); return FAILURE; } // Launch firefox hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI, &processID); if (FAILED(hr)) { Fail(true, L"ActivateApplication result %X", hr); return RETRY; } Log(L"Activation succeeded."); // automation.py picks up on this, don't mess with it. Log(L"METRO_BROWSER_PROCESS=%d", processID); HANDLE child = OpenProcess(SYNCHRONIZE, FALSE, processID); if (!child) { Fail(false, L"Couldn't find child process. (%d)", GetLastError()); return FAILURE; } Log(L"Waiting on child process..."); MSG msg; DWORD waitResult = WAIT_TIMEOUT; HANDLE handles[2] = { child, gTestOutputPipe }; while ((waitResult = MsgWaitForMultipleObjects(2, handles, FALSE, INFINITE, QS_ALLINPUT)) != WAIT_OBJECT_0) { if (waitResult == WAIT_FAILED) { Log(L"Wait failed (errno=%d)", GetLastError()); break; } else if (waitResult == WAIT_OBJECT_0 + 1) { ReadPipe(); } else if (waitResult == WAIT_OBJECT_0 + 2 && PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } ReadPipe(); CloseHandle(gTestOutputPipe); CloseHandle(child); Log(L"Exiting."); return SUCCESS; }
static bool Launch() { Log(L"Launching browser..."); DWORD processID; // The interface that allows us to activate the browser CComPtr<IApplicationActivationManager> activateMgr; if (FAILED(CoCreateInstance(CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_IApplicationActivationManager, (void**)&activateMgr))) { Fail(L"CoCreateInstance CLSID_ApplicationActivationManager failed."); return false; } HRESULT hr; WCHAR appModelID[256]; // Activation is based on the browser's registered app model id if (!GetDefaultBrowserAppModelID(appModelID, (sizeof(appModelID)/sizeof(WCHAR)))) { Fail(L"GetDefaultBrowserAppModelID failed."); return false; } Log(L"App model id='%s'", appModelID); // Hand off focus rights if the terminal has focus to the out-of-process // activation server (explorer.exe). Without this the metro interface // won't launch. if (GetForegroundWindow() == GetConsoleWindow()) { hr = CoAllowSetForegroundWindow(activateMgr, NULL); if (FAILED(hr)) { Fail(L"CoAllowSetForegroundWindow result %X", hr); return false; } } Log(L"Harness process id: %d", GetCurrentProcessId()); // Because we can't pass command line args, we store params in a // tests.ini file in dist/bin which the browser picks up on launch. CStringA testFilePath; if (sFirefoxPath.GetLength()) { // Use the firefoxpath passed to us by the test harness int index = sFirefoxPath.ReverseFind('\\'); if (index == -1) { Fail(L"Bad firefoxpath path"); return false; } testFilePath = sFirefoxPath.Mid(0, index); testFilePath += "\\"; testFilePath += kMetroTestFile; } else { // Use the module path char path[MAX_PATH]; if (!GetModuleFileNameA(NULL, path, MAX_PATH)) { Fail(L"GetModuleFileNameA errorno=%d", GetLastError()); return false; } char* slash = strrchr(path, '\\'); if (!slash) return false; *slash = '\0'; // no trailing slash testFilePath = path; testFilePath += "\\"; testFilePath += kMetroTestFile; } Log(L"Writing out tests.ini to: '%s'", CStringW(testFilePath)); HANDLE hTestFile = CreateFileA(testFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hTestFile == INVALID_HANDLE_VALUE) { Fail(L"CreateFileA errorno=%d", GetLastError()); return false; } DeleteTestFileHelper dtf(testFilePath); CStringA asciiParams = sAppParams; if (!WriteFile(hTestFile, asciiParams, asciiParams.GetLength(), NULL, 0)) { CloseHandle(hTestFile); Fail(L"WriteFile errorno=%d", GetLastError()); return false; } FlushFileBuffers(hTestFile); CloseHandle(hTestFile); // Create a named stdout pipe for the browser if (!SetupTestOutputPipe()) { Fail(L"SetupTestOutputPipe failed (errno=%d)", GetLastError()); return false; } // Launch firefox hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI, &processID); if (FAILED(hr)) { Fail(L"ActivateApplication result %X", hr); return false; } Log(L"Activation succeeded. processid=%d", processID); HANDLE child = OpenProcess(SYNCHRONIZE, FALSE, processID); if (!child) { Fail(L"Couldn't find child process. (%d)", GetLastError()); return false; } Log(L"Waiting on child process..."); MSG msg; DWORD waitResult = WAIT_TIMEOUT; HANDLE handles[2] = { child, gTestOutputPipe }; while ((waitResult = MsgWaitForMultipleObjects(2, handles, FALSE, INFINITE, QS_ALLINPUT)) != WAIT_OBJECT_0) { if (waitResult == WAIT_FAILED) { Log(L"Wait failed (errno=%d)", GetLastError()); break; } else if (waitResult == WAIT_OBJECT_0 + 1) { ReadPipe(); } else if (waitResult == WAIT_OBJECT_0 + 2 && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } ReadPipe(); CloseHandle(gTestOutputPipe); CloseHandle(child); Log(L"Exiting."); return true; }