从C#中的Process.Start启动cmd.exe时,无法识别Telnet命令

时间:2017-07-06 07:43:57

标签: c# cmd telnet

我已经在控制面板上打开了telnet选项 - 程序/功能。 虽然telnet手动工作正常,但是当我在我的C#库下面运行时,我收到了这个错误:

  

"'远程登录'不被视为内部或外部命令,   可操作的程序或批处理文件。"

这是我用来启动Telnet的代码:

Process.Start("cmd", "/k telnet")

这与在手动命令提示符下运行它之间的区别是什么?如何克服这种差异?

2 个答案:

答案 0 :(得分:2)

Telnet是一个程序,始终安装在系统文件夹中。这也意味着,它总是在路上。您需要启动cmd.exe才能启动telnet.exe。只需使用

Process.Start("telnet.exe");

使用arguments参数将参数传递给telnet本身,例如主机,日志文件等:

Process.Start("telnet.exe","localhost 80 -f mylog.txt");

还有其他可能更好的选择。

使用Telnet库

您可以使用Telnet库并直接连接到服务器,例如使用Telnet NuGet package

using (Client client = new Client("localhost",80, new System.Threading.CancellationToken()))
{
    await client.WriteLine("abcd");
    string response = await client.ReadAsync();
    Console.WriteLine(response);
}

使用PowerShell

Telnet通常用于测试与Web服务器的连接,而不是实际发送命令。在这种情况下,您可以使用PowerShell的Test-NetConnection来接收有关连接的诊断信息:

using System.Management.Automation;

var ps = PowerShell.Create()
                    .AddCommand("test-netconnection")
                    .AddArgument("localhost")
                    .AddParameter("CommonTCPPort", "HTTP");
var results = cmd.Invoke();
foreach (dynamic result in results)
{
    Console.WriteLine($"{result.TcpTestSucceeded} {result.SourceAddress}");
}

确保添加正确的Powershell NuGet软件包Microsoft.PowerShell.5.ReferenceAssemblies,而不是不受支持且已弃用的System.Management.Automation软件包

PowerShell的优势在于您可以通过添加更多AddComandAddScript来调用命令和脚本。每个命令都将接收前一个命令的输出。您可以使用Import-CSV从文件中读取服务器和端口列表,并将输出通过管道传输到Test-NetConnection

答案 1 :(得分:0)

通过控制面板安装 Telnet客户端 - 程序和功能 - 打开或关闭Windows功能,将telnet.exe安装到目录%SystemRoot%\System32

在64位Windows上,目录%SystemRoot%\System32适用于x64应用程序。因此,安装的可执行文件telnet.exe也是64位版本。该目录还包含64位版本的cmd.exe

系统环境变量 PATH 还包含%SystemRoot%\System32,负责在没有文件扩展名且没有路径的情况下执行时查找%SystemRoot%\System32\cmd.exe%SystemRoot%\System32\telnet.exe

但是对于包含32位版本可执行文件的x86应用程序,还有目录%SystemRoot%\SysWOW64

Microsoft在MSDN文章WOW64 Implementation DetailsFile System Redirector中解释了x86应用程序对%SystemRoot%\System32的文件系统访问权限如何自动重定向到%SystemRoot%\SysWOW64

安装 Telnet客户端时,telnet.exe中未安装32位版本的%SystemRoot%\SysWOW64

所以会发生什么:

Process.Start("cmd", "/k telnet")

当C#库编译为64位应用程序使用的64位库时,Windows x64会查找并启动查找并启动%SystemRoot%\System32\cmd.exe的{​​{1}}。

但是当C#库被编译为32位应用程序使用的32位库时,Windows x64通过文件系统重定向器%SystemRoot%\System32\telnet.exe查找并启动,该文件系统重定向器%SystemRoot%\SysWOW64\cmd.exe找不到列出文件扩展名的telnet.*在当前目录中的环境变量 PATHEXT 或环境变量 PATH 的任何目录中,因为目录telnet.exe中没有文件%SystemRoot%\SysWOW64

最好的解决方案绝对是使用C#库中的静态(或动态)telnet库,使其独立于telnet.exe,如Panagiotis Kanavos所示。在我看来,每个C#程序员通过进程调用使用外部可执行文件是一种耻辱,C#代码也可以很容易地由程序员编写。使用搜索词C# telnet的任何万维网搜索引擎都会返回大量带有解决方案的页面,例如Stack Overflow上的C# Telnet Library

当然,也可以使用GetEnvironmentVariable方法获取环境变量 SystemRoot 的第一个值,以获取Windows目录的路径,甚至可以使用GetWindowsDirectory或{{更好3}}方法。

然后将此字符串值与"\\System32\\telnet.exe"连接到一个新字符串,并使用GetSystemWindowsDirectory方法检查具有该完整路径的文件是否存在。如果在安装了32位版本的telnet.exe的Windows x86上存在该文件,如果C#应用程序也是x86应用程序,或者在安装了64位telnet.exe的Windows x64上,如果C#应用程序是x64应用程序,则具有完整路径和文件扩展名的文件名可用于进程调用。

否则将Windows目录路径与"\\Sysnative\\telnet.exe"连接,并检查是否存在具有该完整路径的文件。如果在安装了64位版本的telnet.exe的Windows x64上如果C#应用程序是x86应用程序,则为真,则可以使用此路径在32位应用程序中运行64位telnet客户端可执行文件。

但如果失败,则根本不会安装telnet.exe,这就是为什么在C#代码应用程序中使用telnet.exe通常是不可取的。

老实说,我不明白为什么在C#库中有代码只会启动执行telnet.exe的命令进程而没有选项,因此需要用户输入并且在telnet客户端会话终止后保持命令进程运行。 C#库函数可以替换为Windows桌面上的telnet.exe快捷方式或用户的Windows开始菜单中的快捷方式。