如何从Delphi执行WSL

时间:2019-06-11 15:55:20

标签: delphi windows-10 windows-subsystem-for-linux

我的系统上安装了Linux子系统Windows(WSL),它运行正常。但是从我的Delphi代码来看,它根本不起作用。

我正在尝试编写代码以执行“ C:\ Windows \ System32 \ wsl.exe”以运行任何Linux命令(为进行测试,我尝试执行df.groupby(['A', 'B']).size().reset_index(level=1).apply(list,1).\ groupby(level=0).\ apply(list).reset_index().values.tolist() Out[125]: [['a', [['class1', 2], ['class2', 1]]], ['b', [['class12', 1], ['class13', 1]]]] wsl echo foo)。但这只是不起作用,它声称该文件将不存在。

到目前为止,我有一个使用uname来执行某些命令并从stdout读取输出的函数。只要我正在执行Windows应用程序,它就可以正常工作。即我可以做CreateProcess。更具体地说:

cmd /C echo foo

这只是给我“ foo”。

但是,每当我尝试执行wsl时,它都声称该文件不存在。当我检查时,它确实存在或至少似乎存在。我可以在十六进制编辑器中打开它。因此,即使Windows将其作为某种虚拟文件或可能的某种形式提供,这实际上也是一个文件。我了解“ echo”是内置的,而不是真实文件。但是在那种情况下,wsl应该运行并给我“ echo:找不到命令”。因此,如果实际上不存在某些文件,则为wsl.exe。

CreateProcess(PChar('C:\Windows\System32\cmd.exe'), PChar('/C echo foo'), nil, nil, true, 0, nil, nil, StartupInfo, ProcessInfo); 返回false,CreateProcess给我2,表示“系统找不到指定的文件”。那就缺少wsl.exe,事实并非如此。

我通过直接执行编译后的exe文件(不在Delphi中)尝试了同样的方法,并使用“以管理员身份运行”尝试了同样的方法。结果相同。

我可以使用Java(即GetLastError())执行wsl并读取其输出,而不会出现任何问题。因此,这应该是可能的。仅在Delphi中不起作用。

1 个答案:

答案 0 :(得分:0)

这实际上只是重定向。我要做的就是像这样禁用它:

function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  External 'Kernel32.dll' Name 'Wow64DisableWow64FsRedirection';
function Wow64RevertWow64FsRedirection(Wow64FsEnableRedirection: LongBool) : boolean; StdCall;
  External 'Kernel32.dll' Name 'Wow64RevertWow64FsRedirection';

// ...

function TSomeClass.Execute(const ApplicationName, CommandLine: String; out Output: String): boolean;
var 
  WOW64reditrection : LongBool;
  // ...
begin
  if not Wow64DisableWow64FsRedirection(WOW64reditrection) then
    raise Exception.Create('Could not disable Wow64FsRedirection');
  try
    // ...
  finally
    if (not Wow64RevertWow64FsRedirection(WOW64reditrection)) then
      raise Exception.Create('Could not revert Wow64FsRedirection');
  end;
end;