【问题标题】:Telnet is not recognized command when cmd.exe is started from Process.Start in C#从 C# 中的 Process.Start 启动 cmd.exe 时无法识别 Telnet 命令
【发布时间】:2017-12-10 02:16:38
【问题描述】:

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

"'telnet' 未被识别为内部或外部命令, 可运行的程序或批处理文件。”

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

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

这与从命令提示符手动运行有什么区别,我该如何克服这种区别?

【问题讨论】:

  • Telnet 是一个程序。您可以像启动 cmd.exe 或 Word.exe 一样启动它。您不需要先启动 Cmd。只需将路径传递给 telnet.exe
  • @Mofi 错误与平台无关。这是一个确实启动cmd的调用。是cmd 找不到telnet
  • @Mofi 简而言之,您是说telnet.exe 在 SysWOW64 中不存在,但它不存在。你为什么一开始不这么说?
  • @Mofi 你可以把 both cmets 放在一起写一个好的答案。第一条评论本身不够清楚。第二个清楚地解释了问题所在

标签: c# cmd telnet


【解决方案1】:

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

【讨论】:

  • 感谢 Panagiotis。我唯一的问题是 Mofi 提到的重定向。除非我可以重定向,否则它总是说无法识别 Telent。 \
  • 然后使用库。无论如何,您都无法控制telnet.exe 的启动方式-您必须至少重定向输入/输出流才能发送命令
【解决方案2】:

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

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

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

但另外还有一个目录 %SystemRoot%\SysWOW64 用于 32 位应用程序,其中包含 32 位版本的可执行文件。

Microsoft 在文档页面 WOW64 Implementation DetailsFile System Redirector 中解释了如何将 32 位应用程序对 %SystemRoot%\System32 的文件系统访问自动重定向到 %SystemRoot%\SysWOW64

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

那么接下来会发生什么:

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

当 C# 库编译为 64 位应用程序使用的 64 位库时,64 位 Windows 会找到并启动 %SystemRoot%\System32\cmd.exe,后者会找到并启动 %SystemRoot%\System32\telnet.exe

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


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

当然也可以使用GetEnvironmentVariable方法获取环境变量SystemRoot的第一个值来获取Windows目录的路径,或者使用GetWindowsDirectoryGetSystemWindowsDirectory方法更好。

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

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

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

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

【讨论】:

  • 感谢 Mofi - 详细信息对于了解幕后工作原理非常有用。是的,%SystemRoot%\SysWOW64 下没有 telnet.exe。但是解决方案是什么?更改 Process.Start(@"C:\Windows\System32\cmd.exe", "/k telnet") 不适用于重定向。我需要更改我的环境变量或编辑注册
猜你喜欢
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 2021-06-22
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多