Вы должны войти, чтобы создавать сообщения и темы.

Проблема передачи русских букв в SshNet

Здравствуйте всем. Нужна помощь с библиотекой SshNet, но может, у кого-то, похожая проблема была и в других проектах. Ситуация в том, что я хочу передать ssh-комманду, которая содержит в себе русские буквы. Для примера взял команду вывода формы сообщения:
DISPLAY=:0 zenity --info --text="какой-то текст"

Если ее скопировать в putty, то все прекрасно работает, а из C# zenity выдает ошибку: "This option is not available. Please see --help for all possible usages."
Если же русские слова заменить на английские, то все прекрасно работает даже в C#. Я подумал, что дело в кодировке. Переделал определение sshclient

SshClient SshClient = new SshClient(new ConnectionInfo(IPSSH, 22, SSHLogin, new PasswordAuthenticationMethod(SSHLogin, SSHPass)) { Encoding = Encoding.UTF8 });

Далее пытался идти двумя путями:
1. Отправить текс как есть

var cmd = SshClient.CreateCommand("DISPLAY=:0 zenity --info --text=\"Какой-то текст\"");
cmd.Execute();
Console.WriteLine(cmd.Error);

Это дает ту же ошибку, что я писал выше.
2. Конвертировать всю команду в UTF8

var cmd = SshClient.CreateCommand(Encoding.UTF8.GetString(Encoding.Default.GetBytes("DISPLAY=:0 zenity --info --text=\"Какой-то текст\"")));
cmd.Execute();
Console.WriteLine(cmd.Error);

Результата это не приносит. Ошибка все та же
Пробовал без кавычек передавать одно слово, - и снова на английском все работает, а с русскими буквами - нет. Помогите решить эту дискриминационную проблему, ибо варианты у меня закончились.

Приветствую.
А какая локаль на хосте?

P.S. Кириллица, это моветон.

Я так подозреваю, что русская, ибо и Windows и студия - русские.

Таки русская
Console.WriteLine(CultureInfo.CurrentCulture);
выдает ru-RU

Это не то.
В консоли linux выполните команду Скопированоlocale и там посмотрите.

Цитата: Adler от 26.07.2023, 16:25

Это не то.
В консоли linux выполните команду Скопированоlocale и там посмотрите.

[ch@host-45 ~]$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

 

Решил проверить, передаются ли вообще русские символы вообще. Сделал следующее:

SshClient.RunCommand("echo 'DISPLAY=:0 zenity --info --text=\"цук\"' > /home/ch/data.txt");

На линуксе файл создался и внутри моя команда с русскими буквами. Значит все нормально, подумал я и сделал следующее:

SshClient.RunCommand("echo 'DISPLAY=:0 zenity --info --text=\"цук\"' > /home/ch/data.sh");
            Thread.Sleep(100);
            SshClient.RunCommand("su");
            Thread.Sleep(100);
            SshClient.RunCommand("password");
            Thread.Sleep(100);
            SshClient.RunCommand("chmod 755 /home/ch/data.sh");
            Thread.Sleep(100);
            Console.WriteLine(SshClient.RunCommand("sh /home/ch/data.sh").Error);

И в результате получаю ту же ошибку: "This option is not available. Please see --help for all possible usages."
Однако, если с линукса запустить тот же файл, то все работает. И тут я вообще перестал что-либо понимать. Получается, что русские символы таки передаются, но даже если завернуть все в такие костыли - все равно ничего не получается.

После недели мучений и серфинга в интернете в поисках решения, я удивляюсь, почему я до этого не додумался раньше. В общем я решил проблему передачи русских символов в командах. Метод заключается в том, чтоб передавать не сами символы, а их ASCII коды.
Сначала я сделал простенький метод:

public static string ToAscii(this string value)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in value)
            {
                // Append the ASCII value of the char, followed by a space
                sb.Append($@"&#{(int)c};");
            }
            // Remove the trailing space
            return sb.ToString();
        }

А уже в основном модуле вызывал этот метод для строки и отправлял его в теле команды:

string message = "Здравствуйте...".ToAscii();
            SshClient sshClient = new SshClient("host", "login", "password");
            sshClient.Connect();
            sshClient.RunCommand("DISPLAY=:0 zenity --info --text=\"" + message + "\"");

И все прекрасно работает.

Лайкнул Adler
Adler