Эта проблема оказывается разрешимой. (Хотя, как и в большинстве случаев в Windows, не на 100%).
Функция popen
открывает системную команду, что означает, что она почти наверняка просто принимает строковый аргумент и интерполирует его в cmd.exe /c <here>
.
После некоторых интерактивных экспериментов с cmd.exe /c
в командной строке Windows мы нашли способ запустить программу, в имени которой есть пробелы.
Наивная попытка с кавычками, нет:
C:\>cmd /c "foo bar"
'foo' is not recognized as an internal or external command,
operable program or batch file.
Можем ли мы избежать кавычек с помощью обхода?
C:\>cmd /c ^"foo bar^"
'foo' is not recognized [...]
Как насчет пространства?
C:\>cmd /c foo^ bar
'foo' is not recognized [...]
Как насчет цитирования только пробела?
C:\>cmd /c foo" "bar
'foo" "bar' is not recognized as an internal or external command,
operable program or batch file.
Aha! Это многообещающе! Это на самом деле пытается запустить foo bar
? Посмотрим:
C:\>copy con "foo bar.bat"
echo i am foo bar
^Z
1 file(s) copied.
C:\>cmd /c foo" "bar
C:\>echo i am foo bar
i am foo bar
Aha! Наш пакетный файл с пробелом в имени был запущен!
Итак, теперь я пытаюсь сделать следующее в Visual Studio 2008:
#include <stdio.h>
int main()
{
FILE *in = _popen("C:\\Program\" \"Files\\Internet\" \"Explorer\\iexplore.exe", "r");
if (in) {
char line[200];
printf("successfully opened!\n");
if (fgets(line, 200, in))
fputs(line, stdout);
_pclose(in);
}
return 0;
}
Он отлично запускает Internet Explorer, затем блокирует fgets
до тех пор, пока вы не выйдете из браузера (и не может ничего прочитать, так как нет вывода).
Он работает в MinGW, в котором используется библиотека времени выполнения Microsoft C; на самом деле, я предложил это решение, чтобы исправить ошибку в библиотеке языка программирования, который перенесен в Windows с использованием MinGW.
Предостережения:
Эта уловка не ускользнет от ведущих пробелов. Кажется, это работает для конечных пробелов. Ни то, ни другое не является проблемой; мы не часто видим имена путей, которые начинаются или заканчиваются пробелами, не говоря уже об именах исполняемых путей.
Я также не могу найти способ избежать встроенных двойных кавычек, которые могут встречаться как часть пути, и в то же время обрабатывать пробелы. Люди, вероятно, должны дважды подумать, прежде чем создавать что-то вроде C:\Program Files\Bob's so-called "editor"\bedit.exe
.