mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:14:37 +02:00
TerminalShell: add support for Windows
This commit is contained in:
+12
-8
@@ -191,7 +191,6 @@ set(LIBFASTFETCH_SRC
|
||||
src/common/caching.c
|
||||
src/common/properties.c
|
||||
src/common/font.c
|
||||
src/common/processing.c
|
||||
src/common/format.c
|
||||
src/common/parsing.c
|
||||
src/common/settings.c
|
||||
@@ -204,7 +203,6 @@ set(LIBFASTFETCH_SRC
|
||||
src/logo/image/im6.c
|
||||
src/detection/qt.c
|
||||
src/detection/gtk.c
|
||||
src/detection/terminalShell.c
|
||||
src/detection/vulkan.c
|
||||
src/detection/datetime.c
|
||||
src/detection/title.c
|
||||
@@ -264,6 +262,15 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/users.c
|
||||
)
|
||||
|
||||
if(LINUX OR APPLE OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/users/users_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/detection/disk/disk.c
|
||||
src/detection/terminalShell/terminalShell_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BSD OR APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/sysctl.c
|
||||
@@ -281,10 +288,8 @@ if(LINUX OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/disk/disk.c
|
||||
src/detection/poweradapter/poweradapter_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/processes/processes_linux.c
|
||||
)
|
||||
@@ -312,6 +317,7 @@ endif()
|
||||
|
||||
if(WIN_MSYS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/processing_linux.c
|
||||
src/detection/host/host_windows.cpp
|
||||
src/detection/bios/bios_windows.cpp
|
||||
src/detection/board/board_windows.cpp
|
||||
@@ -329,13 +335,13 @@ if(WIN_MSYS)
|
||||
src/detection/cpuUsage/cpuUsage_nowait_windows.cpp
|
||||
src/detection/memory/memory_windows.cpp
|
||||
src/detection/font/font_windows.cpp
|
||||
src/detection/terminalShell/terminalShell_linux.c
|
||||
src/detection/terminalShell/terminalShell_windows.cpp
|
||||
src/util/windows/wmi.cpp
|
||||
|
||||
# Shared
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/poweradapter/poweradapter_linux.c
|
||||
|
||||
# TODO
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
)
|
||||
@@ -359,11 +365,9 @@ if(APPLE)
|
||||
src/detection/terminalfont/terminalfont_apple.m
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/disk/disk_apple.m
|
||||
src/detection/disk/disk.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/temps/temps_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/opengl/opengl_apple.c
|
||||
src/detection/processes/processes_apple.c
|
||||
)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/processing.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
//We can't use this native version yet because we still use POSIX path ( eg /usr/bin/fish ) at a lot of places.
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
SECURITY_ATTRIBUTES saAttr = {
|
||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||
.lpSecurityDescriptor = NULL,
|
||||
.bInheritHandle = TRUE,
|
||||
};
|
||||
|
||||
HANDLE hChildStdoutRead, hChildStdoutWrite;
|
||||
if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0))
|
||||
return "CreatePipe() failed";
|
||||
|
||||
if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0))
|
||||
return "SetHandleInformation(hChildStdoutRead) failed";
|
||||
|
||||
PROCESS_INFORMATION piProcInfo = {0};
|
||||
STARTUPINFOA siStartInfo = {
|
||||
.cb = sizeof(siStartInfo),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
.hStdOutput = hChildStdoutWrite,
|
||||
};
|
||||
|
||||
FFstrbuf cmdline;
|
||||
ffStrbufInit(&cmdline);
|
||||
for(char* const* parg = argv; *parg; ++parg)
|
||||
{
|
||||
if(cmdline.length > 0)
|
||||
ffStrbufAppendC(&cmdline, ' ');
|
||||
ffStrbufAppendF(&cmdline, "\"%s\"", * parg);
|
||||
}
|
||||
|
||||
BOOL success = CreateProcessA(
|
||||
NULL, // application name
|
||||
cmdline.chars, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
|
||||
CloseHandle(hChildStdoutWrite);
|
||||
if(!success)
|
||||
{
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return "CreateProcessA() failed";
|
||||
}
|
||||
|
||||
char str[128];
|
||||
DWORD nRead;
|
||||
while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0)
|
||||
{
|
||||
ffStrbufAppendNS(buffer, nRead, str);
|
||||
if(nRead < sizeof(str))
|
||||
break;
|
||||
}
|
||||
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return NULL;
|
||||
}
|
||||
@@ -95,7 +95,5 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
//On WSL, the real host can't be detected. Instead use WSL as host.
|
||||
if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL)
|
||||
ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_WSL);
|
||||
else if(getenv("MSYSTEM") != NULL && strcmp(getenv("MSYSTEM"), "MSYS") == 0)
|
||||
ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
#include "detection/internal.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
|
||||
static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) {
|
||||
FFstrbuf fontName;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "terminalfont.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "terminalfont.h"
|
||||
#include "common/font.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "util/apple/osascript.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "common/settings.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
static const char* getSystemMonospaceFont(const FFinstance* instance)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/host/host.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "common/io.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/processing.h"
|
||||
#include "terminalshell.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@@ -94,6 +94,7 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid)
|
||||
strcasecmp(name, "ksh") == 0 ||
|
||||
strcasecmp(name, "fish") == 0 ||
|
||||
strcasecmp(name, "dash") == 0 ||
|
||||
strcasecmp(name, "pwsh") == 0 ||
|
||||
strcasecmp(name, "git-shell") == 0
|
||||
) {
|
||||
ffStrbufAppendS(&result->shellProcessName, name);
|
||||
@@ -256,13 +257,19 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio
|
||||
getShellVersionBash(exe, version);
|
||||
else if(strcasecmp(exeName, "zsh") == 0)
|
||||
getShellVersionZsh(exe, version);
|
||||
else if(strcasecmp(exeName, "fish") == 0)
|
||||
else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0)
|
||||
getShellVersionFish(exe, version);
|
||||
else
|
||||
getShellVersionGeneric(exe, exeName, version);
|
||||
}
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
|
||||
const FFTerminalShellResult*
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
ffDetectTerminalShellPosix
|
||||
#else
|
||||
ffDetectTerminalShell
|
||||
#endif
|
||||
(const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
extern "C" {
|
||||
#include "terminalshell.h"
|
||||
#include "common/processing.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <wchar.h>
|
||||
|
||||
struct ProcessInfo
|
||||
{
|
||||
uint32_t pid;
|
||||
FFstrbuf psName;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr);
|
||||
if(!pEnumerator)
|
||||
return false;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
|
||||
{
|
||||
pEnumerator->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ppid)
|
||||
{
|
||||
uint64_t value;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"ParentProcessId", &value);
|
||||
*ppid = (uint32_t) value;
|
||||
}
|
||||
|
||||
if(pname)
|
||||
ffGetWmiObjString(pclsObj, L"Name", pname);
|
||||
|
||||
if(exe)
|
||||
ffGetWmiObjString(pclsObj, L"ExecutablePath", exe);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getShellVersion(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
char* const argv[] = { exe->chars, "--version", NULL };
|
||||
ffProcessAppendStdOut(version, argv);
|
||||
ffStrbufTrimRight(version, '\n');
|
||||
ffStrbufSubstrAfterLastC(version, ' ');
|
||||
}
|
||||
|
||||
static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(!getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe))
|
||||
return 0;
|
||||
result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1;
|
||||
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->shellProcessName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->shellProcessName, result->shellProcessName.length - 4);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&result->shellProcessName, "pwsh") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->shellProcessName, "PowerShell");
|
||||
getShellVersion(&result->shellExe, &result->shellVersion);
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->shellProcessName, "powershell") == 0)
|
||||
ffStrbufSetS(&result->shellProcessName, "Windows PowerShell");
|
||||
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(!getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe))
|
||||
return 0;
|
||||
result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\');
|
||||
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->terminalProcessName, ".exe"))
|
||||
result->terminalProcessName.length -= 4;
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "WindowsTerminal"))
|
||||
ffStrbufSetS(&result->terminalProcessName, "Windows Terminal");
|
||||
else if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "conhost"))
|
||||
ffStrbufSetS(&result->terminalProcessName, "Console Window Host");
|
||||
|
||||
return ppid;
|
||||
}
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
extern "C"
|
||||
const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance);
|
||||
#endif
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
// This is hacky.
|
||||
// When running inside MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx )
|
||||
// When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way
|
||||
if(getenv("MSYSTEM"))
|
||||
return ffDetectTerminalShellPosix(instance);
|
||||
#endif
|
||||
|
||||
static FFTerminalShellResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.shellProcessName);
|
||||
ffStrbufInitA(&result.shellExe, 128);
|
||||
result.shellExeName = result.shellExe.chars;
|
||||
ffStrbufInit(&result.shellVersion);
|
||||
|
||||
ffStrbufInit(&result.terminalProcessName);
|
||||
ffStrbufInitA(&result.terminalExe, 128);
|
||||
result.terminalExeName = result.terminalExe.chars;
|
||||
|
||||
ffStrbufInit(&result.userShellExe);
|
||||
result.userShellExeName = result.userShellExe.chars;
|
||||
ffStrbufInit(&result.userShellVersion);
|
||||
|
||||
uint32_t ppid = GetCurrentProcessId();
|
||||
if(!getProcessInfo(ppid, &ppid, nullptr, nullptr))
|
||||
return &result;
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
if(ppid == 0)
|
||||
return &result;
|
||||
|
||||
ppid = getTerminalInfo(&result, ppid);
|
||||
if(ppid == 0)
|
||||
return &result;
|
||||
|
||||
return &result;
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
#include "common/io.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/os/os.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "common/properties.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/caching.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/parsing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
|
||||
#define FF_SHELL_MODULE_NAME "Shell"
|
||||
#define FF_SHELL_NUM_FORMAT_ARGS 7
|
||||
@@ -18,7 +18,7 @@ void ffPrintShell(FFinstance* instance)
|
||||
if(instance->config.shell.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell.key);
|
||||
fputs(result->shellExeName, stdout);
|
||||
ffStrbufWriteTo(&result->shellProcessName, stdout);
|
||||
|
||||
if(result->shellVersion.length > 0)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -20,11 +20,7 @@ void ffPrintTerminal(FFinstance* instance)
|
||||
if(instance->config.terminal.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key);
|
||||
|
||||
if(strncmp(result->terminalExeName, result->terminalProcessName.chars, result->terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
|
||||
puts(result->terminalExeName);
|
||||
else
|
||||
ffStrbufPutTo(&result->terminalProcessName, stdout);
|
||||
ffStrbufPutTo(&result->terminalProcessName, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user