TerminalShell: improve shell detection on Windows

This commit is contained in:
李通洲
2022-10-15 11:36:24 +08:00
parent a99ca9a1a1
commit b042b90d9b
2 changed files with 63 additions and 29 deletions
@@ -18,13 +18,16 @@ struct ProcessInfo
static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe)
{
wchar_t query[256] = {};
swprintf(query, 256, L"SELECT Name, ParentProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = %" PRIu32, pid);
swprintf(query, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32,
pname ? L"Name," : L"",
pname ? L"ExecutablePath," : L"",
pid);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr);
if(!pEnumerator)
return false;
IWbemClassObject *pclsObj = NULL;
IWbemClassObject *pclsObj = nullptr;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
@@ -65,20 +68,39 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe"))
ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4);
//Common programs that are between terminal and own process, but are not the shell
if(
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sudo") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "su") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "doas") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "strace") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sshd") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "gdb") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "lldb") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "guake-wrapped") ||
ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug")
) {
ffStrbufClear(&result->shellProcessName);
ffStrbufClear(&result->shellPrettyName);
ffStrbufClear(&result->shellExe);
result->shellExeName = nullptr;
return getShellInfo(result, ppid);
}
ffStrbufClear(&result->shellVersion);
fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion);
if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "pwsh") == 0)
if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "pwsh"))
ffStrbufSetS(&result->shellPrettyName, "PowerShell");
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0)
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell"))
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell");
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell_ise") == 0)
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell_ise"))
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE");
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0)
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "cmd"))
ffStrbufSetS(&result->shellPrettyName, "Command Prompt");
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "nu") == 0)
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "nu"))
ffStrbufSetS(&result->shellPrettyName, "nushell");
else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0)
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer"))
{
ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell
return 0;
@@ -100,28 +122,30 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid)
ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4);
if(
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "pwsh") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "cmd") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "bash") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "zsh") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "fish") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "nu") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell") == 0 ||
ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell_ise") == 0
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "pwsh") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "cmd") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "bash") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "zsh") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "fish") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "nu") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell") ||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell_ise")
) {
//We are nested shell
ffStrbufClear(&result->terminalProcessName);
ffStrbufClear(&result->terminalPrettyName);
ffStrbufClear(&result->terminalExe);
result->terminalExeName = NULL;
result->terminalExeName = nullptr;
return getTerminalInfo(result, ppid);
}
if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal") == 0)
if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal"))
ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal");
else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0)
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "conhost"))
ffStrbufSetS(&result->terminalPrettyName, "Console Window Host");
else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0)
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "Code"))
ffStrbufSetS(&result->terminalPrettyName, "Visual Studio Code");
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer"))
ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer");
return ppid;
@@ -139,23 +163,23 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0
) return;
const char* term = NULL;
const char* term = nullptr;
//SSH
if(getenv("SSH_CONNECTION") != NULL)
if(getenv("SSH_CONNECTION") != nullptr)
term = getenv("SSH_TTY");
//Windows Terminal
if(!term && (
getenv("WT_SESSION") != NULL ||
getenv("WT_PROFILE_ID") != NULL
getenv("WT_SESSION") != nullptr ||
getenv("WT_PROFILE_ID") != nullptr
)) term = "Windows Terminal";
//Alacritty
if(!term && (
getenv("ALACRITTY_SOCKET") != NULL ||
getenv("ALACRITTY_LOG") != NULL ||
getenv("ALACRITTY_WINDOW_ID") != NULL
getenv("ALACRITTY_SOCKET") != nullptr ||
getenv("ALACRITTY_LOG") != nullptr ||
getenv("ALACRITTY_WINDOW_ID") != nullptr
)) term = "Alacritty";
//Normal Terminal
+12 -2
View File
@@ -147,7 +147,7 @@ static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
return memcmp(strbuf->chars, comp->chars, length + 1);
}
static inline FF_C_NODISCARD int ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp)
static inline FF_C_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp)
{
return ffStrbufComp(strbuf, comp) == 0;
}
@@ -157,7 +157,7 @@ static inline FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const cha
return strcmp(strbuf->chars, comp);
}
static inline FF_C_NODISCARD int ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp)
static inline FF_C_NODISCARD bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp)
{
return ffStrbufCompS(strbuf, comp) == 0;
}
@@ -167,11 +167,21 @@ static inline FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, co
return strcasecmp(strbuf->chars, comp);
}
static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp)
{
return ffStrbufIgnCaseCompS(strbuf, comp) == 0;
}
static inline FF_C_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
{
return ffStrbufIgnCaseCompS(strbuf, comp->chars);
}
static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp)
{
return ffStrbufIgnCaseComp(strbuf, comp) == 0;
}
static inline FF_C_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str)
{
return strstr(strbuf->chars, str) != NULL;