在 C# 中从 Process.Start 启动 cmd.exe 时,Telnet 不是可识别的命令
Telnet is not recognized command when cmd.exe is started from Process.Start in C#
我已经打开了控制面板上的 telnet 选项 - program/features。
虽然 telnet 手动工作正常,但是当我从我的 C# 库中 运行 下面时,我收到此错误:
"'telnet' is not recognized as an internal or external command,
operable program or batch file."
这是我用来启动 Telnet 的代码:
Process.Start("cmd", "/k telnet")
这与从命令提示符手动 运行 有什么区别?我该如何克服这个区别?
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 的优势在于您只需添加更多 AddComand
、AddScript
调用即可将命令和脚本链接在一起。每个命令都将接收前一个命令的输出。您可以使用 Import-CSV
从文件中读取服务器和端口列表,并将输出通过管道传输到 Test-NetConnection
通过控制面板-程序和功能-打开或关闭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 Details and File System Redirector 中解释了 32 位应用程序对 %SystemRoot%\System32
的文件系统访问如何自动重定向到 %SystemRoot%\SysWOW64
。
在安装 Telnet Client.
时 %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 中列出,因为没有文件 telnet.exe
在目录 %SystemRoot%\SysWOW64
.
中
最好的解决方案肯定是在 C# 库中使用静态(或动态)telnet 库来独立于 telnet.exe
,正如 Panagiotis Kanavos. In my point of view it is a shame for every C# programmer using external executables via a process call for which C# code can be quite easily also written by the programmer. Using any world wide web search engine with the search term C# telnet
returns lots of pages with solutions, for example C# Telnet Library 在 Stack Overflow 上所建议的那样。
当然也可以使用GetEnvironmentVariable method to get path to Windows directory, or even better using GetWindowsDirectory or GetSystemWindowsDirectory方法获取环境变量SystemRoot的第一个值。
然后将此字符串值与 "\System32\telnet.exe"
连接成一个新字符串,并使用 File.Exists 方法检查具有该完整路径的文件是否存在。如果该文件存在于安装了 32 位版本 telnet.exe
的 32 位 Windows 如果 C# 应用程序也是 32 位应用程序,或者存在于安装了 64 位 Windows 的 64 位 Windows =11=] 如果 C# 应用程序是 64 位应用程序,则安装此文件名以及完整路径和文件扩展名可以在进程调用中使用。
否则将 Windows 目录路径与 "\Sysnative\telnet.exe"
连接起来,并检查是否存在具有该完整路径的文件。如果在 64 位 Windows 上安装了 64 位版本的 telnet.exe
如果 C# 应用程序是 32 位应用程序,则可以从 32 位 运行使用此路径应用 64 位 telnet 客户端可执行文件。
但如果同样失败,则根本不会安装 telnet.exe
,这就是为什么通常不建议在 C# 代码应用程序中使用 telnet.exe
的原因。
老实说,我不明白为什么要在 C# 库中包含代码,它只是启动命令进程执行 telnet.exe
而没有选项,因此需要用户输入并保持命令进程 运行 telnet 客户端会话终止后 ning。 C# 库函数可以在 Windows 桌面或 Windows 用户的开始菜单中替换为 telnet.exe
的快捷方式。
我已经打开了控制面板上的 telnet 选项 - program/features。 虽然 telnet 手动工作正常,但是当我从我的 C# 库中 运行 下面时,我收到此错误:
"'telnet' is not recognized as an internal or external command, operable program or batch file."
这是我用来启动 Telnet 的代码:
Process.Start("cmd", "/k telnet")
这与从命令提示符手动 运行 有什么区别?我该如何克服这个区别?
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 的优势在于您只需添加更多 AddComand
、AddScript
调用即可将命令和脚本链接在一起。每个命令都将接收前一个命令的输出。您可以使用 Import-CSV
从文件中读取服务器和端口列表,并将输出通过管道传输到 Test-NetConnection
通过控制面板-程序和功能-打开或关闭Windows功能安装Telnet客户端安装telnet.exe
进入目录 %SystemRoot%\System32
.
目录 %SystemRoot%\System32
用于 64 位 Windows 上的 64 位应用程序。因此安装的可执行文件 telnet.exe
也是 64 位版本。此目录还包含 cmd.exe
.
系统环境变量PATH包含%SystemRoot%\System32
,负责查找%SystemRoot%\System32\cmd.exe
和%SystemRoot%\System32\telnet.exe
执行时不带文件扩展名不带路径.
但另外还有目录 %SystemRoot%\SysWOW64
用于 32 位应用程序,其中包含 32 位版本的可执行文件。
Microsoft 在文档页面 WOW64 Implementation Details and File System Redirector 中解释了 32 位应用程序对 %SystemRoot%\System32
的文件系统访问如何自动重定向到 %SystemRoot%\SysWOW64
。
在安装 Telnet Client.
时%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 中列出,因为没有文件 telnet.exe
在目录 %SystemRoot%\SysWOW64
.
最好的解决方案肯定是在 C# 库中使用静态(或动态)telnet 库来独立于 telnet.exe
,正如 Panagiotis Kanavos. In my point of view it is a shame for every C# programmer using external executables via a process call for which C# code can be quite easily also written by the programmer. Using any world wide web search engine with the search term C# telnet
returns lots of pages with solutions, for example C# Telnet Library 在 Stack Overflow 上所建议的那样。
当然也可以使用GetEnvironmentVariable method to get path to Windows directory, or even better using GetWindowsDirectory or GetSystemWindowsDirectory方法获取环境变量SystemRoot的第一个值。
然后将此字符串值与 "\System32\telnet.exe"
连接成一个新字符串,并使用 File.Exists 方法检查具有该完整路径的文件是否存在。如果该文件存在于安装了 32 位版本 telnet.exe
的 32 位 Windows 如果 C# 应用程序也是 32 位应用程序,或者存在于安装了 64 位 Windows 的 64 位 Windows =11=] 如果 C# 应用程序是 64 位应用程序,则安装此文件名以及完整路径和文件扩展名可以在进程调用中使用。
否则将 Windows 目录路径与 "\Sysnative\telnet.exe"
连接起来,并检查是否存在具有该完整路径的文件。如果在 64 位 Windows 上安装了 64 位版本的 telnet.exe
如果 C# 应用程序是 32 位应用程序,则可以从 32 位 运行使用此路径应用 64 位 telnet 客户端可执行文件。
但如果同样失败,则根本不会安装 telnet.exe
,这就是为什么通常不建议在 C# 代码应用程序中使用 telnet.exe
的原因。
老实说,我不明白为什么要在 C# 库中包含代码,它只是启动命令进程执行 telnet.exe
而没有选项,因此需要用户输入并保持命令进程 运行 telnet 客户端会话终止后 ning。 C# 库函数可以在 Windows 桌面或 Windows 用户的开始菜单中替换为 telnet.exe
的快捷方式。