Skip to content

Instantly share code, notes, and snippets.

@PetarKirov
Last active October 8, 2019 12:32
Show Gist options
  • Select an option

  • Save PetarKirov/663704e8f8bad60aeaa3e6159c92c860 to your computer and use it in GitHub Desktop.

Select an option

Save PetarKirov/663704e8f8bad60aeaa3e6159c92c860 to your computer and use it in GitHub Desktop.
Get Process Path
void main(string[] args)
{
import std.process : userShell;
import std.stdio : writeln;
auto res = getProcessPath(args.length == 2? args[1] : userShell());
res.writeln;
}
/++
Gets the path to a command by running it and then using OS APIs to query
information about the running process.
Supports:
* Windows
* Linux
+/
string getProcessPath(string cmd)
{
import std.exception : assumeUnique;
import std.process : spawnProcess;
import std.stdio : File;
version (Posix)
enum devNull = "/dev/null";
else version (Windows)
enum devNull = "nul";
auto nullFile = File(devNull, "w");
auto pid = spawnProcess(cmd, nullFile, nullFile, nullFile);
enum bufSize = 1024;
auto buf = new char[](bufSize);
uint bytesWritten = bufSize;
version (Windows)
{
import std.windows.syserror : wenforce;
QueryFullProcessImageNameA(pid.osHandle, 0, buf.ptr, &bytesWritten).wenforce("fail");
}
else version (linux)
{
import core.sys.posix.unistd : readlink;
import std.exception : errnoEnforce;
import std.format : fmt = format;
import std.string : toStringz;
bytesWritten = cast(uint)readlink(
"/proc/%s/exe".fmt(pid.osHandle).toStringz,
buf.ptr, buf.length - 1);
errnoEnforce(bytesWritten != -1);
}
else
static assert(0, "Unsupported platform");
return buf.ptr[0 .. bytesWritten].assumeUnique;
}
version (Windows)
{
import core.sys.windows.windows : BOOL, HANDLE, DWORD, LPSTR, PDWORD;
// _WIN32_WINNT >= 0x0600
extern (Windows) BOOL QueryFullProcessImageNameA(
HANDLE hProcess,
DWORD dwFlags,
LPSTR lpExeName,
PDWORD lpdwSize
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment