ОС формирует массив char* arr[] в который попадает строка командной строки (она же может быть написана в ярлыке). Строка разбивается на отдельные слова пробелами.
Например при запуске файла
C:/programs/myprog.exe -t 39483 "hello world"
будет сформирован строковой массив
char* arr[] = {"C:/programs/myprog.exe", "-t", "39483", "hello world"};
и будет вызвана функция майн как
main(sizeof(arr)/sizeof(char*), arr);
arr[0] содержит C:/programs/myprog.exe
arr[1] содержит -t
arr[2] содержит 39483
arr[3] содержит hello world (из за того что он был взят в кавычки попало оба слова)
так что main получит размер массива в первый параметр (4 в данном примере) и указатель на строки во второй и сможет получить к нему доступ. Как видно имя файла само по себе является одним из элементов массива, так что он пустым не бывает.
Это приблизительная схема, подробностей взаимодействия ОС с исполняемыми файлами я не знаю)