TerminalShell (Windows): improves logic of GUI program check

This commit is contained in:
李通洲
2026-02-28 10:06:13 +08:00
parent 3e25b213b1
commit 000a688bb6
2 changed files with 43 additions and 22 deletions
+20 -8
View File
@@ -220,9 +220,6 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
if (hProcess == NULL)
return false;
if (gui)
*gui = GetGuiResources(hProcess, GR_GDIOBJECTS) > 0;
if(ppid)
{
PROCESS_BASIC_INFORMATION info = {};
@@ -235,6 +232,7 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
else
return false;
}
if(exe)
{
// TODO: It's possible to query the command line with `NtQueryInformationProcess(60/*ProcessCommandLineInformation*/)` since Windows 8.1
@@ -243,18 +241,32 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
ULONG size;
if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageFileNameWin32, &buffer, sizeof(buffer), &size)))
{
UNICODE_STRING* imageName = (UNICODE_STRING*)buffer;
ffStrbufSetNWS(exe, imageName->Length / sizeof(wchar_t), imageName->Buffer);
UNICODE_STRING* imagePath = (UNICODE_STRING*)buffer;
ffStrbufSetNWS(exe, imagePath->Length / sizeof(wchar_t), imagePath->Buffer);
if (exePath) ffStrbufSet(exePath, exe);
if (pname && exeName)
{
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
ffStrbufSetS(pname, *exeName);
}
}
else
return false;
}
if(pname && exeName)
if (gui)
{
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
ffStrbufSetS(pname, *exeName);
SECTION_IMAGE_INFORMATION info = {};
ULONG size;
if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageInformation, &info, sizeof(info), &size)))
{
assert(size == sizeof(info));
*gui = info.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI;
}
else
return false;
}
return true;
@@ -22,15 +22,17 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
{
uint32_t ppid = 0;
bool gui = false;
while (pid != 0 && ffProcessGetInfoWindows(pid, &ppid, &result->processName, &result->exe, &result->exeName, &result->exePath, NULL))
while (pid != 0 && ffProcessGetInfoWindows(pid, &ppid, &result->processName, &result->exe, &result->exeName, &result->exePath, &gui))
{
ffStrbufSet(&result->prettyName, &result->processName);
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
if (ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
//Common programs that are between terminal and own process, but are not the shell
if(
if (
!gui && (
ffStrbufIgnCaseEqualS(&result->prettyName, "sudo") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "su") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "gdb") ||
@@ -41,8 +43,8 @@ static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
ffStrbufContainIgnCaseS(&result->prettyName, "time") ||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
) {
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmuC") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
)) {
ffStrbufClear(&result->processName);
ffStrbufClear(&result->prettyName);
ffStrbufClear(&result->exe);
@@ -52,13 +54,18 @@ static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
}
result->pid = pid;
result->ppid = ppid;
if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
if (gui)
{
ffStrbufSetS(&result->prettyName, "Windows Explorer"); // Started without shell
// Started without shell
// In this case, terminal process will be created by fastfetch itself.
ppid = 0;
if (ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
ffStrbufSetS(&result->prettyName, "Windows Explorer");
}
else
{
result->ppid = ppid;
}
break;
@@ -91,9 +98,11 @@ static void setShellInfoDetails(FFShellResult* result)
{
if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0)
{
ffStrbufAppendS(&result->prettyName, " (with Clink ");
ffGetFileVersion(module.szExePath, NULL, &result->prettyName);
ffStrbufAppendC(&result->prettyName, ')');
FF_STRBUF_AUTO_DESTROY clinkVersion = ffStrbufCreate();
if (ffGetFileVersion(module.szExePath, NULL, &clinkVersion))
ffStrbufAppendF(&result->prettyName, " (with Clink %s)", clinkVersion.chars);
else
ffStrbufAppendS(&result->prettyName, " (with Clink)");
break;
}
}
@@ -251,11 +260,11 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
}
uint32_t ppid = 0;
bool hasGui;
bool gui;
while (pid != 0 && ffProcessGetInfoWindows(pid, &ppid, &result->processName, &result->exe, &result->exeName, &result->exePath, &hasGui))
while (pid != 0 && ffProcessGetInfoWindows(pid, &ppid, &result->processName, &result->exe, &result->exeName, &result->exePath, &gui))
{
if(!hasGui || ffStrbufIgnCaseEqualS(&result->processName, "far.exe")) // Far includes GUI objects...
if (!gui)
{
//We are in nested shell
ffStrbufClear(&result->processName);