在通过控制面板 - 程序和功能 - 打开或关闭 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 和 File 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目录的路径,或者使用GetWindowsDirectory或GetSystemWindowsDirectory方法更好。
然后将此字符串值与"\\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的快捷方式。