我必须通过代码启动 VPN 连接 (Fortinet)。 我有一个建立连接的 cmd 文件。 如果我在 shell 上调用 cmd 文件,它工作得很好。 当我通过 Process.Start 调用它时,它什么也不做。 它没有抛出任何异常,它似乎执行但 VPN 没有连接。
在标准输出上,我可以读取放在 cmd 文件中的回显(因此它正在执行正确的文件)。 我启动了一个 ping -d 来查看 vpn 何时启动,当我通过 shell 调用它时它会在几秒钟内启动,通过 C# 则不会。
我也试过 sleep (30000)但没有。
我的命令(ConnectFile.cmd):
@echo off
@echo Connecting to VPN
"C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe" connect -s "vpn myvpn"
我的代码(connectFile 和 disconnectFile 是包含 cmd 文件完整路径的字符串):
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = connectFile;
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(connectFile) ?? "";
System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo);
System.Threading.Thread.Sleep(30000);
base.GetFiles(folder);
}
finally
{
System.Diagnostics.Process.Start(disconnectFile);
}
最佳答案
您必须将参数分开。 FileName
用于 exe 文件,而不是整个 shell 命令(您明确表示不使用 shell)。因此,将参数放入 ProcessStartInfo
中的 Arguments
属性。
在你的例子中,参数应该是:
- 文件名 -
C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe
(无引号) - 参数 -
connect -s "vpn myvpn"
(同样,没有引用)
其次,如果捕获它,则必须读取标准输出。如果在您读取之前输出缓冲区已满,被调用的进程将停止工作——它必须等待缓冲区被清空。如果您确定应用程序实际上会在某个时刻完成,只需删除Thread.Sleep
并立即调用ReadToEnd
。否则,使用例如。异步读取获取数据。
另外,设置 WorkingDirectory
通常是个好主意。即使应用程序不需要工作目录中的任何数据,它也更安全,因为只有管理员才能更改Program Files
- 这有助于防止 DLL 注入(inject)攻击。
关于c# - Process.Start() 什么都不做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22780352/