简体   繁体   English

当从 C# 中的 Process.Start 启动 cmd.exe 时,Telnet 不是可识别的命令

[英]Telnet is not recognized command when cmd.exe is started from Process.Start in C#

I have already switch on the telnet option on control panel - program/features.我已经打开控制面板上的 telnet 选项 - 程序/功能。 Though telnet worked fine manually, but when I run below from my C# library, I am getting this error:虽然 telnet 手动工作正常,但是当我从我的 C# 库运行下面时,我收到此错误:

"'telnet' is not recognized as an internal or external command, operable program or batch file." “'telnet' 不是内部或外部命令,也不是可运行的程序或批处理文件。”

This is the code I use to start Telnet:这是我用来启动 Telnet 的代码:

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

What makes the difference between this and running it from the command prompt manually and how do I overcome this difference?这与从命令提示符手动运行它有什么区别,我该如何克服这种差异?

Telnet is a program, always installed in the system folder. Telnet 是一个程序,总是安装在系统文件夹中。 Which also means, it's always in the path.这也意味着,它总是在路上。 You don't need to start cmd.exe in order to start telnet.exe .无需启动cmd.exe即可启动telnet.exe Just use只需使用

Process.Start("telnet.exe");

Use the arguments parameter to pass arguments to telnet itself, eg the host, log file etc:使用arguments参数将参数传递给 telnet 本身,例如主机、日志文件等:

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

There other, probably better options.还有其他可能更好的选择。

Use a Telnet Library使用 Telnet 库

You can use a Telnet library and connect to a server directly, eg using the Telnet NuGet package :您可以使用 Telnet 库并直接连接到服务器,例如使用Telnet NuGet 包

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

Use PowerShell使用 PowerShell

Telnet is often used to test connectivity to a web server, not to actually send commands. Telnet 通常用于测试与 Web 服务器的连接,而不是实际发送命令。 In this case, you could use PowerShell's Test-NetConnection to receive diagnostics about the connection:在这种情况下,您可以使用 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}");
}

Make sure you add the correct Powershell NuGet package, Microsoft.PowerShell.5.ReferenceAssemblies , not the unsupported and abandoned System.Management.Automation package确保添加正确的 Powershell NuGet 包Microsoft.PowerShell.5.ReferenceAssemblies ,而不是不受支持和废弃的System.Management.Automation

The advantage of PowerShell is that you can chain commands and scripts together just by adding more AddComand , AddScript calls. PowerShell 的优点是您可以通过添加更多AddComandAddScript调用将命令和脚本链接在一起。 Each command will receive the output of the previous one.每个命令都将接收前一个命令的输出。 You could use Import-CSV to read a list of servers and ports from a file and pipe the output to Test-NetConnection您可以使用Import-CSV从文件中读取服务器和端口列表,并将输出通过管道传输到Test-NetConnection

On installing Telnet Client via Control Panel - Programs and Features - Turn Windows features on or off there is installed telnet.exe into directory %SystemRoot%\System32 .在通过控制面板 - 程序和功能 - 打开或关闭 Windows 功能安装Telnet 客户端时,将telnet.exe安装到目录%SystemRoot%\System32中。

The directory %SystemRoot%\System32 is for 64-bit applications on 64-bit Windows.目录%SystemRoot%\System32用于 64 位 Windows 上的 64 位应用程序。 Therefore the installed executable telnet.exe is also the 64-bit version.因此安装的可执行文件telnet.exe也是 64 位版本。 This directory contains also the 64-bit version of cmd.exe .此目录还包含 64 位版本的cmd.exe

System environment variable PATH contains %SystemRoot%\System32 which is responsible for finding %SystemRoot%\System32\cmd.exe and %SystemRoot%\System32\telnet.exe when being executed without file extension and without path.系统环境变量PATH中包含%SystemRoot%\System32 ,负责查找%SystemRoot%\System32\cmd.exe%SystemRoot%\System32\telnet.exe在不带文件扩展名和不带路径执行时。

But there is additionally the directory %SystemRoot%\SysWOW64 for 32-bit applications containing the 32-bit versions of the executables.但是,对于包含 32 位版本的可执行文件的 32 位应用程序,还有目录%SystemRoot%\SysWOW64

Microsoft explains with the documentation pages WOW64 Implementation Details and File System Redirector how a file system access to %SystemRoot%\System32 by a 32-bit application is redirected automatically to %SystemRoot%\SysWOW64 . Microsoft 在文档页面WOW64 实施细节文件系统重定向器中解释了 32 位应用程序对%SystemRoot%\System32的文件系统访问如何自动重定向到%SystemRoot%\SysWOW64

There is no 32-bit version of telnet.exe installed into %SystemRoot%\SysWOW64 on installing Telnet Client .在安装Telnet Client时, %SystemRoot%\SysWOW64中没有安装 32 位版本的telnet.exe

So what happens on:那么会发生什么:

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

When the C# library is compiled as 64-bit library used by a 64-bit application, 64-bit Windows finds and starts %SystemRoot%\System32\cmd.exe which finds and then starts %SystemRoot%\System32\telnet.exe .当 C# 库被编译为 64 位应用程序使用的 64 位库时,64 位 Windows 会查找并启动%SystemRoot%\System32\cmd.exe ,后者查找并启动%SystemRoot%\System32\telnet.exe

But when the C# library is compiled as 32-bit library used by a 32-bit application, 64-bit Windows finds and starts via file system redirector %SystemRoot%\SysWOW64\cmd.exe which cannot find telnet.* with a file extension listed in environment variable PATHEXT in current directory or any directory of environment variable PATH because there is no file telnet.exe in directory %SystemRoot%\SysWOW64 .但是,当 C# 库被编译为 32 位应用程序使用的 32 位库时,64 位 Windows 会通过文件系统重定向器%SystemRoot%\SysWOW64\cmd.exe查找并启动,它找不到带有文件扩展名的telnet.*在当前目录或环境变量PATH的任何目录中的环境变量PATHEXT中列出,因为目录%SystemRoot%\SysWOW64中没有文件telnet.exe


The best solution is definitely to use a static (or dynamic) telnet library in the C# library to be independent on telnet.exe as suggested by Panagiotis Kanavos .最好的解决方案肯定是按照Panagiotis Kanavos的建议,在 C# 库中使用静态(或动态)telnet 库以独立于telnet.exe 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.在我看来,对于每个通过进程调用使用外部可执行文件的 C# 程序员来说,C# 代码也可以很容易地由程序员编写,这是一种耻辱。 Using any world wide web search engine with the search term C# telnet returns lots of pages with solutions, for example C# Telnet Library on Stack Overflow.使用任何带有搜索词C# telnet的万维网搜索引擎会返回许多包含解决方案的页面,例如 Stack Overflow 上的C# Telnet 库

Of course it is also possible to get first value of environment variable SystemRoot using GetEnvironmentVariable method to get path to Windows directory, or even better using GetWindowsDirectory or GetSystemWindowsDirectory method.当然,也可以使用GetEnvironmentVariable方法获取环境变量SystemRoot的第一个值以获取 Windows 目录的路径,或者使用GetWindowsDirectoryGetSystemWindowsDirectory方法更好。

Then concatenate this string value with "\\System32\\telnet.exe" to a new string and check if the file with that full path exists using File.Exists method.然后将此字符串值与"\\System32\\telnet.exe"连接成一个新字符串,并使用File.Exists方法检查具有该完整路径的文件是否存在。 If that file exists on 32-bit Windows with 32-bit version of telnet.exe installed if C# application is also a 32-bit application or on 64-bit Windows with 64-bit telnet.exe installed if C# application is a 64-bit application, then this file name with full path and file extension can be used in a process call.如果 C# 应用程序也是 32 位应用程序,则该文件存在于安装了 32 位版本的telnet.exe的 32 位 Windows 上,或者如果 C# 应用程序是 64 位应用程序,则该文件存在于安装了 64 位telnet.exe的 64 位 Windows 上bit 应用程序,那么这个具有完整路径和文件扩展名的文件名可以在进程调用中使用。

Otherwise concatenate the Windows directory path with "\\Sysnative\\telnet.exe" and check if file with that full path exists.否则将 Windows 目录路径与"\\Sysnative\\telnet.exe"连接起来,并检查是否存在具有该完整路径的文件。 If this is true on 64-bit Windows with 64-bit version of telnet.exe installed if C# application is a 32-bit application, it would be possible to run from within 32-bit application the 64-bit telnet client executable using this path.如果在安装了 64 位版本的telnet.exe的 64 位 Windows 上是这样,如果 C# 应用程序是 32 位应用程序,则可以使用此从 32 位应用程序中运行 64 位 telnet 客户端可执行文件小路。

But if that fails also, telnet.exe is not installed at all which is the reason why usage of telnet.exe from within a C# code application is in general not advisable.但如果同样失败,则根本没有安装telnet.exe ,这就是为什么通常不建议在 C# 代码应用程序中使用telnet.exe的原因。

Honestly, I don't understand why to have code in a C# library which just starts a command process executing telnet.exe without options and therefore requiring user input and which keeps the command process running after telnet client session terminated.老实说,我不明白为什么要在 C# 库中包含代码,它只是启动一个命令进程执行telnet.exe而没有选项,因此需要用户输入并在 telnet 客户端会话终止后保持命令进程运行。 The C# library function can be replaced by a shortcut to telnet.exe on Windows desktop or in Windows start menu of the user. C#库函数可以在Windows桌面或用户的Windows开始菜单中用telnet.exe的快捷方式代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过Process.Start()调用时,为什么“cmd.exe / C命令”不会结束? - Why won't “cmd.exe /C command” end when called via Process.Start()? C#进程cmd.exe-无法将“ hadoop”识别为内部或外部命令,可操作程序或批处理文件 - C# Process cmd.exe - 'hadoop' is not recognized as an internal or external command, operable program or batch file 为什么要Process.Start(“cmd.exe”,进程); 不行? - Why does Process.Start(“cmd.exe”, process); not work? 如何在Process.Start()中通过cmd.exe运行cmd.exe和大量开关 - How to run cmd.exe and a lot of switches via cmd.exe in Process.Start() cmd.exe中的TELNET命令与C#中的Socket编程之间的区别 - Difference between TELNET Command in cmd.exe and Socket programming in c# 使用process.start()运行cmd.exe时如何引用存储在visual studio项目资源中的exe文件 - How to reference an exe file stored in visual studio project resource when running cmd.exe using process.start() 从 C# 运行不带 cmd.exe 的 windows 命令 - Run windows command without cmd.exe from C# 使用C#中的cmd.exe - Using cmd.exe from C# Visual Studio x86工具,常规cmd.exe,Process.Start() - Visual Studio x86 tools, normal cmd.exe, Process.Start() 如何终止cmd.exe启动的进程 - How to kill a process started by cmd.exe
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM