From 7fe31126d121e810dd93641ae6582e9ab1dac16e Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Mon, 4 Oct 2021 11:59:26 -0400 Subject: Added ability to specify a working directory on opening a terminal. Released memory on calls using the ANSI creation function. --- ProcessUtils.cpp | 11 +++++++---- ProcessUtils.h | 2 +- RadTerminal.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++------ RadTerminal.h | 4 ++-- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/ProcessUtils.cpp b/ProcessUtils.cpp index e3effc9..efafc00 100644 --- a/ProcessUtils.cpp +++ b/ProcessUtils.cpp @@ -16,7 +16,7 @@ namespace { spd->hPC = NULL; } - SubProcessData CreateSubProcess(LPCTSTR cmd, COORD size, HANDLE hInput, HANDLE hOutput, bool bUseConPty) + SubProcessData CreateSubProcess(LPCTSTR cmd, LPCTSTR wdir, COORD size, HANDLE hInput, HANDLE hOutput, bool bUseConPty) { SubProcessData spd = {}; @@ -87,8 +87,11 @@ namespace { } TCHAR localcmd[MAX_PATH]; + TCHAR localwdir[MAX_PATH]; _tcscpy_s(localcmd, cmd); - if (!CreateProcess(nullptr, localcmd, nullptr, nullptr, bInheritHandles, dwCreationFlags, nullptr, nullptr, &si.StartupInfo, &spd.pi)) + if(wdir != nullptr) + _tcscpy_s(localwdir, wdir); + if (!CreateProcess(nullptr, localcmd, nullptr, nullptr, bInheritHandles, dwCreationFlags, nullptr, wdir == nullptr ? nullptr : localwdir, &si.StartupInfo, &spd.pi)) { spd.hr = HRESULT_FROM_WIN32(GetLastError()); CleanupSubProcess(&spd); @@ -101,7 +104,7 @@ namespace { } } -SubProcessData CreateSubProcess(LPCTSTR cmd, COORD size, bool bUseConPty) +SubProcessData CreateSubProcess(LPCTSTR cmd, LPCTSTR wdir, COORD size, bool bUseConPty) { SubProcessData spd = {}; @@ -119,7 +122,7 @@ SubProcessData CreateSubProcess(LPCTSTR cmd, COORD size, bool bUseConPty) spd.hr = HRESULT_FROM_WIN32(GetLastError()); if (spd.hr == S_OK) - spd = CreateSubProcess(cmd, size, hReadPipeInput, hWritePipeOutput, bUseConPty); + spd = CreateSubProcess(cmd, wdir, size, hReadPipeInput, hWritePipeOutput, bUseConPty); if (spd.hr == S_OK) { diff --git a/ProcessUtils.h b/ProcessUtils.h index 0b6f304..d545c69 100644 --- a/ProcessUtils.h +++ b/ProcessUtils.h @@ -10,6 +10,6 @@ struct SubProcessData HANDLE hOutput; }; -SubProcessData CreateSubProcess(LPCTSTR cmd, COORD zsCon, bool bUseConPty); +SubProcessData CreateSubProcess(LPCTSTR cmd, LPCTSTR wdir, COORD zsCon, bool bUseConPty); void CleanupSubProcess(const SubProcessData* spd); UINT GetIcon(const SubProcessData* spd, HICON *phIconLarge, HICON *phIconSmall); diff --git a/RadTerminal.cpp b/RadTerminal.cpp index 5be8fce..5dae48e 100644 --- a/RadTerminal.cpp +++ b/RadTerminal.cpp @@ -122,6 +122,7 @@ struct RadTerminalCreate COORD szCon; int sb; std::tstring strCommand; + std::tstring workDirectory; }; void LoadRegistry(RadTerminalCreate& rtc, LPCWSTR strSubKey) @@ -193,6 +194,7 @@ RadTerminalCreate GetTerminalCreate(bool bParseCmdLine, std::tstring profile) rtc.sb = 1000; //rtc.strCommand = _T("%COMSPEC%"); rtc.strCommand = _T("cmd"); + rtc.workDirectory = _T(""); LoadRegistry(rtc, _T("Default")); LoadRegistry(rtc, profile.c_str()); @@ -205,7 +207,7 @@ RadTerminalCreate GetTerminalCreate(bool bParseCmdLine, std::tstring profile) #ifdef BUILD_AS_DLL extern "C" { - __declspec(dllexport) HWND WINAPI CreateTerminalWindowExW(HINSTANCE hInstance, HWND hParent, LPWSTR fontFace, int fontSize, BOOL darkMode) + __declspec(dllexport) HWND WINAPI CreateTerminalWindowExW(HINSTANCE hInstance, HWND hParent, LPWSTR command, LPWSTR working_directory, LPWSTR fontFace, int fontSize, BOOL darkMode) { HWND hRet; @@ -217,6 +219,12 @@ extern "C" { if (fontFace != NULL) rtc.strFontFace = std::tstring(fontFace); + if (command != NULL) + rtc.strCommand = std::tstring(command); + + if (working_directory != NULL) + rtc.workDirectory = std::tstring(working_directory); + hRet = CreateWindowEx( WS_EX_ACCEPTFILES, MAKEINTATOM(GetRadTerminalAtom(hInstance)), @@ -238,10 +246,10 @@ extern "C" { return hRet; } - __declspec(dllexport) HWND WINAPI CreateTerminalWindowExA(HINSTANCE hInstance, HWND hParent, LPCSTR fontFace, int fontSize, BOOL darkMode) + __declspec(dllexport) HWND WINAPI CreateTerminalWindowExA(HINSTANCE hInstance, HWND hParent, LPCSTR command, LPCSTR working_directory, LPCSTR fontFace, int fontSize, BOOL darkMode) { HWND hRet; - LPWSTR fontFaceW; + LPWSTR fontFaceW, commandW, workDirW; fontFaceW = NULL; if (fontFace != NULL) { @@ -252,12 +260,41 @@ extern "C" { } } - return CreateTerminalWindowExW(hInstance, hParent, fontFaceW, fontSize, darkMode); + commandW = NULL; + if (command != NULL) { + int fflen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, command, strlen(command), NULL, 0); + commandW = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (fflen + 1) * sizeof(WCHAR)); + if (commandW != NULL) { + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, command, strlen(command), commandW, fflen + 1); + } + } + + workDirW = NULL; + if (working_directory != NULL) { + int fflen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, working_directory, strlen(working_directory), NULL, 0); + workDirW = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (fflen + 1) * sizeof(WCHAR)); + if (workDirW != NULL) { + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, working_directory, strlen(working_directory), workDirW, fflen + 1); + } + } + + hRet = CreateTerminalWindowExW(hInstance, hParent, commandW, workDirW, fontFaceW, fontSize, darkMode); + + if (fontFaceW != NULL) + HeapFree(GetProcessHeap(), 0, fontFaceW); + + if (commandW != NULL) + HeapFree(GetProcessHeap(), 0, commandW); + + if (workDirW != NULL) + HeapFree(GetProcessHeap(), 0, workDirW); + + return hRet; } __declspec(dllexport) HWND WINAPI CreateTerminalWindow(HINSTANCE hInstance, HWND hParent, BOOL darkMode) { - return CreateTerminalWindowExW(hInstance, hParent, NULL, -1, darkMode); + return CreateTerminalWindowExW(hInstance, hParent, NULL, NULL, NULL, -1, darkMode); } } /* extern "C" */ @@ -870,7 +907,7 @@ BOOL RadTerminalWindowOnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) ZeroMemory(data, sizeof(RadTerminalData)); SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data); - data->spd = CreateSubProcess(rtc->strCommand.c_str(), rtc->szCon, true); + data->spd = CreateSubProcess(rtc->strCommand.c_str(), rtc->workDirectory.length() > 0 ? rtc->workDirectory.c_str() : nullptr, rtc->szCon, true); if (data->spd.hr != S_OK) { ShowError(hWnd, _T("CreateSubProcess"), data->spd.hr); diff --git a/RadTerminal.h b/RadTerminal.h index 382871b..a70c315 100644 --- a/RadTerminal.h +++ b/RadTerminal.h @@ -8,8 +8,8 @@ #ifndef BUILD_AS_DLL #ifdef RADTERM_DLL -__declspec(dllimport) HWND WINAPI CreateTerminalWindowExW(HINSTANCE hInstance, HWND hParent, LPWSTR fontFace, int fontSize, BOOL darkMode); -__declspec(dllimport) HWND WINAPI CreateTerminalWindowExA(HINSTANCE hInstance, HWND hParent, LPCSTR fontFace, int fontSize, BOOL darkMode); +__declspec(dllimport) HWND WINAPI CreateTerminalWindowExW(HINSTANCE hInstance, HWND hParent, LPWSTR command, LPWSTR working_directory, LPWSTR fontFace, int fontSize, BOOL darkMode); +__declspec(dllimport) HWND WINAPI CreateTerminalWindowExA(HINSTANCE hInstance, HWND hParent, LPCSTR command, LPCSTR working_directory, LPCSTR fontFace, int fontSize, BOOL darkMode); __declspec(dllimport) HWND WINAPI CreateTerminalWindow(HINSTANCE hInstance, HWND hParent, BOOL darkMode); #endif -- cgit v1.2.3