void CSetPgIntegr::RegisterShell(LPCWSTR asName, LPCWSTR asMode, LPCWSTR asConfig, LPCWSTR asCmd, LPCWSTR asIcon) { if (!asName || !*asName) asName = L"ConEmu"; if (!asCmd || !*asCmd) asCmd = CONEMU_HERE_CMD; asCmd = SkipNonPrintable(asCmd); #ifdef _DEBUG CEStr szMode(asMode); _ASSERTE(szMode.IsSwitch(L"-here") || szMode.IsSwitch(L"-inside") || szMode.IsSwitch(L"-inside:")); #endif CEStr lsExta; LPCWSTR pszExtraArgs = gpConEmu->MakeConEmuStartArgs(lsExta, asConfig); size_t cchMax = _tcslen(gpConEmu->ms_ConEmuExe) + (asMode ? (_tcslen(asMode) + 3) : 0) + (pszExtraArgs ? (_tcslen(pszExtraArgs) + 1) : 0) + _tcslen(asCmd) + 32; wchar_t* pszCmd = (wchar_t*)malloc(cchMax*sizeof(*pszCmd)); if (!pszCmd) return; //[HKEY_CURRENT_USER\Software\Classes\*\shell\ConEmu inside] //"Icon"="C:\\Program Files\\ConEmu\\ConEmu.exe,1" //[HKEY_CURRENT_USER\Software\Classes\*\shell\ConEmu inside\command] //@="C:\\Program Files\\ConEmu\\ConEmu.exe /inside /config shell /cmd {powershell} -cur_console:n" //[HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\ConEmu inside] //"Icon"="C:\\Program Files\\ConEmu\\ConEmu.exe,1" //[HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\ConEmu inside\command] //@="C:\\Program Files\\ConEmu\\ConEmu.exe /inside /config shell /cmd {powershell} -cur_console:n" //[HKEY_CURRENT_USER\Software\Classes\Directory\shell\ConEmu inside] //"Icon"="C:\\Program Files\\ConEmu\\ConEmu.exe,1" //[HKEY_CURRENT_USER\Software\Classes\Directory\shell\ConEmu inside\command] //@="C:\\Program Files\\ConEmu\\ConEmu.exe /inside /config shell /dir \"%1\" /cmd {powershell} -cur_console:n" //[HKEY_CURRENT_USER\Software\Classes\Drive\shell\ConEmu inside] //"Icon"="C:\\Program Files\\ConEmu\\ConEmu.exe,1" //[HKEY_CURRENT_USER\Software\Classes\Drive\shell\ConEmu inside\command] //@="C:\\Program Files\\ConEmu\\ConEmu.exe /inside /config shell /dir \"%1\" /cmd {powershell} -cur_console:n" int iSucceeded = 0; bool bHasLibraries = IsWindows7; for (int i = 1; i <= 6; i++) { _wcscpy_c(pszCmd, cchMax, L"\""); _wcscat_c(pszCmd, cchMax, gpConEmu->ms_ConEmuExe); _wcscat_c(pszCmd, cchMax, L"\" "); // `-here`, `-inside` or `-inside:cd ...` if (asMode && *asMode) { bool bQ = IsQuotationNeeded(asMode); if (bQ) _wcscat_c(pszCmd, cchMax, L"\""); _wcscat_c(pszCmd, cchMax, asMode); _wcscat_c(pszCmd, cchMax, bQ ? L"\" " : L" "); } // -FontDir, -LoadCfgFile, -Config, etc. if (pszExtraArgs && *pszExtraArgs) { _wcscat_c(pszCmd, cchMax, pszExtraArgs); _wcscat_c(pszCmd, cchMax, L" "); } LPCWSTR pszRoot = NULL; switch (i) { case 1: pszRoot = L"Software\\Classes\\*\\shell"; break; case 2: pszRoot = L"Software\\Classes\\Directory\\Background\\shell"; break; case 3: if (!bHasLibraries) continue; pszRoot = L"Software\\Classes\\LibraryFolder\\Background\\shell"; break; case 4: pszRoot = L"Software\\Classes\\Directory\\shell"; _wcscat_c(pszCmd, cchMax, L"-dir \"%1\" "); break; case 5: pszRoot = L"Software\\Classes\\Drive\\shell"; _wcscat_c(pszCmd, cchMax, L"-dir \"%1\" "); break; case 6: // Issue 1191: ConEmu was launched instead of explorer from taskbar pinned library icon continue; //if (!bHasLibraries) // continue; //pszRoot = L"Software\\Classes\\LibraryFolder\\shell"; //_wcscat_c(pszCmd, cchMax, L"-dir \"%1\" "); //break; } bool bCmdKeyExist = false; if (*asCmd == L'/') { CEStr lsArg; LPCWSTR pszTemp = asCmd; while (0 == NextArg(&pszTemp, lsArg)) { if (lsArg.OneOfSwitches(L"-run",L"-runlist",L"-cmd",L"-cmdlist")) { bCmdKeyExist = true; break; } } } if (!bCmdKeyExist) _wcscat_c(pszCmd, cchMax, L"-run "); _wcscat_c(pszCmd, cchMax, asCmd); HKEY hkRoot; if (0 == RegCreateKeyEx(HKEY_CURRENT_USER, pszRoot, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkRoot, NULL)) { HKEY hkConEmu; if (0 == RegCreateKeyEx(hkRoot, asName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkConEmu, NULL)) { // Если задана "иконка" if (asIcon) RegSetValueEx(hkConEmu, L"Icon", 0, REG_SZ, (LPBYTE)asIcon, (lstrlen(asIcon)+1)*sizeof(*asIcon)); else RegDeleteValue(hkConEmu, L"Icon"); // Команда HKEY hkCmd; if (0 == RegCreateKeyEx(hkConEmu, L"command", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkCmd, NULL)) { if (0 == RegSetValueEx(hkCmd, NULL, 0, REG_SZ, (LPBYTE)pszCmd, (lstrlen(pszCmd)+1)*sizeof(*pszCmd))) iSucceeded++; RegCloseKey(hkCmd); } RegCloseKey(hkConEmu); } RegCloseKey(hkRoot); } } free(pszCmd); }
// Вызывается для инициализации из Settings::LoadSettings() HWND CConEmuInside::InsideFindParent() { bool bFirstStep = true; DWORD nParentPID = 0; PROCESSENTRY32 pi = {sizeof(pi)}; EnumFindParentArg find = {}; if (!m_InsideIntegration) { return NULL; } if (mh_InsideParentWND) { if (IsWindow(mh_InsideParentWND)) { if (m_InsideIntegration == ii_Simple) { // We cover all client area of mh_InsideParentWND in this mode _ASSERTE(mh_InsideParentRel==NULL); mh_InsideParentRel = NULL; } _ASSERTE(mh_InsideParentWND!=NULL); goto wrap; } else { if (m_InsideIntegration == ii_Simple) { DisplayLastError(L"Specified window not found"); SetInsideParentWND(NULL); goto wrap; } _ASSERTE(IsWindow(mh_InsideParentWND)); SetInsideParentWND(mh_InsideParentRel = NULL); } } _ASSERTE(m_InsideIntegration!=ii_Simple); if (mn_InsideParentPID) { if ((mn_InsideParentPID == GetCurrentProcessId()) || !GetProcessInfo(mn_InsideParentPID, &pi)) { DisplayLastError(L"Invalid parent process specified"); m_InsideIntegration = ii_None; SetInsideParentWND(NULL); goto wrap; } nParentPID = mn_InsideParentPID; } else { PROCESSENTRY32 pi = {sizeof(pi)}; if (!GetProcessInfo(GetCurrentProcessId(), &pi) || !pi.th32ParentProcessID) { DisplayLastError(L"GetProcessInfo(GetCurrentProcessId()) failed"); m_InsideIntegration = ii_None; SetInsideParentWND(NULL); goto wrap; } nParentPID = pi.th32ParentProcessID; } // Do window enumeration find.nPID = nParentPID; ::EnumWindows(EnumInsideFindParent, (LPARAM)&find); if (!find.hParentRoot) { int nBtn = MsgBox(L"Can't find appropriate parent window!\n\nContinue in normal mode?", MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2); if (nBtn != IDYES) { SetInsideParentWND(INSIDE_PARENT_NOT_FOUND); return mh_InsideParentWND; // Закрыться! } // Продолжить в обычном режиме m_InsideIntegration = ii_None; SetInsideParentWND(NULL); goto wrap; } mh_InitialRoot = find.hParentRoot; mn_InsideParentPID = nParentPID; HWND hExistConEmu; if ((hExistConEmu = InsideFindConEmu(find.hParentRoot)) != NULL) { _ASSERTE(FALSE && "Continue to create tab in existing instance"); // Если в проводнике уже есть ConEmu - открыть в нем новую вкладку gpSetCls->SingleInstanceShowHide = sih_None; LPCWSTR pszCmdLine = GetCommandLine(); CEStr lsArg; LPCWSTR pszCmd = pszCmdLine; while (0 == NextArg(&pszCmd, lsArg)) { if (lsArg.OneOfSwitches(L"-runlist",L"-cmdlist")) { pszCmd = NULL; break; } else if (lsArg.OneOfSwitches(L"-run",L"-cmd")) { break; } } gpConEmu->RunSingleInstance(hExistConEmu, (pszCmd && *pszCmd) ? (pszCmd) : NULL); SetInsideParentWND(INSIDE_PARENT_NOT_FOUND); return mh_InsideParentWND; // Закрыться! } // Теперь нужно найти дочерние окна // 1. в которое будем внедряться // 2. по которому будем позиционироваться // 3. для синхронизации текущего пути InsideFindShellView(find.hParentRoot); RepeatCheck: if (!isInsideWndSet() || (!mh_InsideParentRel && (m_InsideIntegration == ii_Explorer))) { wchar_t szAddMsg[128] = L"", szMsg[1024]; if (bFirstStep) { bFirstStep = false; if (TurnExplorerTipPane(szAddMsg)) { goto RepeatCheck; } } _wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"%sCan't find appropriate shell window!\nUnrecognized layout of the Explorer.\n\nContinue in normal mode?", szAddMsg); int nBtn = MsgBox(szMsg, MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2); if (nBtn != IDYES) { SetInsideParentWND(INSIDE_PARENT_NOT_FOUND); return mh_InsideParentWND; // Закрыться! } m_InsideIntegration = ii_None; SetInsideParentWND(NULL); goto wrap; } wrap: if (!isInsideWndSet()) { m_InsideIntegration = ii_None; } else { GetWindowThreadProcessId(mh_InsideParentWND, &mn_InsideParentPID); // Для мониторинга папки GetCurrentDirectory(countof(ms_InsideParentPath), ms_InsideParentPath); int nLen = lstrlen(ms_InsideParentPath); if ((nLen > 3) && (ms_InsideParentPath[nLen-1] == L'\\')) { ms_InsideParentPath[nLen-1] = 0; } } return mh_InsideParentWND; }
int main(int argc, char** argv) { HeapInitialize(); for (int i=0; i<argc; i++) { if (strcmp(argv[i], "-verbose")==0 || strcmp(argv[i], "--verbose")==0) gbVerifyVerbose = true; } // Tests { Verify_Step("ls1(`Test`)"); CEStr ls1(L"Test"); Verify0((ls1.ms_Val && 0==wcscmp(ls1.ms_Val,L"Test")),"ls1==`Test`"); Verify_Step("ls12 = ls1.Detach()"); /* Store ptr for Verify test result */ LPCWSTR pszPtr = ls1.ms_Val; CEStr ls2 = ls1.Detach(); Verify2((ls2.ms_Val && !ls1.ms_Val && ls2.ms_Val==pszPtr),"ls2.ms_Val{x%p}==pszPtr{x%p}",ls2.ms_Val,pszPtr); } { Verify_Step("ls3 = `Test3`"); CEStr ls3 = L"Test3"; Verify0((ls3.ms_Val && 0==wcscmp(ls3.ms_Val,L"Test3")),"ls3==`Test3`"); Verify_Step("ls4 = (LPCWSTR)ls3.ms_Val"); CEStr ls4 = static_cast<LPCWSTR>(ls3.ms_Val); Verify2((ls4.ms_Val && ls4.ms_Val != ls3.ms_Val),"ls4.ms_Val{x%p}!=ls3.ms_Val{x%p}",ls4.ms_Val,ls3.ms_Val); Verify_Step("ls5 = lstrdup(ls3)"); CEStr ls5 = lstrdup(ls3); Verify0((ls5.ms_Val && 0==wcscmp(ls5.ms_Val,L"Test3")),"ls5==`Test3`"); Verify_Step("ls6(lstrdup(ls3))"); CEStr ls6(lstrdup(ls3)); Verify0((ls6.ms_Val && 0==wcscmp(ls6.ms_Val,L"Test3")),"ls6==`Test3`"); } { Verify_Step("NextArg and Switch comparison"); LPCWSTR pszCmd = L"conemu.exe /c/dir -run -inside=0x800 /cmdlist \"-inside=\\eCD /d %1\" -bad|switch "; CEStr ls; Verify0((0==NextArg(&pszCmd,ls)),"NextArg conemu.exe"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch()"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg /c/dir"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch()"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -run"); Verify0((ls.OneOfSwitches(L"/cmd",L"/run")),"OneOfSwitches(/cmd,/run)"); Verify0((!ls.OneOfSwitches(L"/cmd",L"/cmdlist")),"!OneOfSwitches(/cmd,/cmdlist)"); Verify0((ls.IsSwitch(L"-run")),"IsSwitch(-run)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -inside=0x800"); Verify0((ls.IsSwitch(L"-inside=")),"IsSwitch(-inside=)"); Verify0((ls.OneOfSwitches(L"-inside",L"-inside=")),"OneOfSwitches(-inside,-inside=)"); Verify0((!ls.IsSwitch(L"-inside")),"!IsSwitch(-inside)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg /cmdlist"); Verify0((ls.IsSwitch(L"-cmdlist")),"IsSwitch(-cmdlist)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg \"-inside=\\eCD /d %1\""); Verify0((ls.IsSwitch(L"-inside:")),"IsSwitch(-inside=)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -bad|switch"); Verify0((ls.Compare(L"-bad|switch")==0),"Compare(-bad|switch)"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch"); } { Verify_Step("-new_console parser tests"); LPCWSTR pszTest = L"-new_console:a \\\"-new_console:c\\\" `-new_console:d:C:\\` -cur_console:b"; LPCWSTR pszCmp = L"\\\"-new_console:c\\\" `-new_console:d:C:\\`"; RConStartArgs arg; arg.pszSpecialCmd = lstrdup(pszTest); arg.ProcessNewConArg(); int iCmp = lstrcmp(arg.pszSpecialCmd, pszCmp); Verify0((iCmp==0),"arg.pszSpecialCmd==\\\"-new_console:c\\\" `-new_console:d:C:\\`"); Verify_Step("RConStartArgs::RunArgTests()"); RConStartArgs::RunArgTests(); Verify0(!gbVerifyFailed,"RConStartArgs tests passed"); } { Verify_Step("msprintf tests"); wchar_t szBuffer[200]; msprintf(szBuffer, countof(szBuffer), L"%u %03u %03u %i %x %02X %02X %04x %08X", 123, 98, 4567, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const wchar_t szStd[] = L"123 098 4567 -234 12ab 0A ABC 01a0 0765ABCD"; int iCmp = lstrcmp(szBuffer, szStd); WVerify2((iCmp==0),L"`%s` (msprintf[W])\n `%s` (standard)", szBuffer, szStd); char szBufA[200]; msprintf(szBufA, countof(szBufA), "%u %i %x %02X %02X %04x %08X", 123, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const char szStdA[] = "123 -234 12ab 0A ABC 01a0 0765ABCD"; iCmp = lstrcmpA(szBufA, szStdA); Verify2((iCmp==0),"`%s` (msprintf[A])\n `%s` (standard)", szBufA, szStdA); } if (gbVerifyFailed) Verify_MsgFail("Some tests failed!"); else Verify_MsgOk("All done"); return gbVerifyFailed ? 99 : 0; }