Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
1

Перекодировка из окна консоли

01.06.2018, 09:54. Просмотров 1232. Ответов 10

Добрый день, запускаю из-под своей программы консольное приложение (конкретно dsquery.exe), в итоге получаю вывод в textBox2.Text, но конечно не в нужной мне кодировке. Читал MSDN по Encoding.Convert, пробовал разные варианты (в том числе в этого форума), но так и не смог перекодировать в читаемый русский.
Сейчас кусок кода выглядит так (на названия переменных не обращайте внимания, это копипаст из другого примера, с которым я и развлекался):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                Encoding cp866 = Encoding.GetEncoding(866);
                Encoding unicode = Encoding.GetEncoding(1251);
                Process dcquery = new Process();
                dcquery.StartInfo.FileName = "dsquery.exe";
                dcquery.StartInfo.Arguments = "user -samid " + textBox1.Text + "*";
                dcquery.StartInfo.UseShellExecute = false;
                dcquery.StartInfo.RedirectStandardOutput = true;
                dcquery.StartInfo.CreateNoWindow = true;
                dcquery.Start();
                
                textBox2.Text = dcquery.StandardOutput.ReadToEnd();
                string buf = textBox2.Text;
                byte[] cp866Bytes = cp866.GetBytes(buf);
                cp866Bytes = Encoding.Convert(cp866, unicode, cp866Bytes);
                buf = unicode.GetString(cp866Bytes);
                textBox2.Text = buf;
 
                dcquery.WaitForExit();
Добавлено через 3 часа 41 минуту
в таком варианте перекодирование происходит, но не получаю искомый русский. понимаю что у нас должно из 866 перекодироваться в 1251, но чего-то не хватает.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2018, 09:54
Ответы с готовыми решениями:

Центральное положение окна консоли
Здравствуйте! Подскажите пожалуйста... Вот в консольном C#(Microsoft Visual Studio 2012) есть в...

Заполнение окна консоли символами
Как можно заполнить окно консоли каким либо символом не выходя за нижнюю границу. По горизонтали...

Скрытие окна консоли во время выполнения приложения
Консольное приложение на .NET 4.0 Как скрыть окно приложения во время его работы? Т.е. чтобы окошко...

Как в консоли вывести надпись по центру строки в зависимости от размера окна?
Чтобы всегда центровалось по центру, и без разницы какой размер окна задан у пользователя.

10
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
04.06.2018, 07:51  [ТС] 2
спасибо всем кто помогал, рабочий вариант такой:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
                Encoding cp866 = Encoding.GetEncoding(866);
                Encoding cp1251 = Encoding.Default;
                Process dcquery = new Process();
                dcquery.StartInfo.FileName = "dsquery.exe";
                dcquery.StartInfo.Arguments = "user -samid " + textBox1.Text + "*";
                dcquery.StartInfo.UseShellExecute = false;
                dcquery.StartInfo.RedirectStandardOutput = true;
                dcquery.StartInfo.CreateNoWindow = true;
                dcquery.Start();
                textBox2.Text = dcquery.StandardOutput.ReadToEnd();
                byte[] cp866Bytes = cp1251.GetBytes(textBox2.Text);
                cp866Bytes = Encoding.Convert(cp866, cp1251, cp866Bytes);
                textBox2.Text = cp1251.GetString(cp866Bytes);
                dcquery.WaitForExit();
Добавлено через 58 минут
Или так:
C#
1
2
3
4
5
6
7
8
9
        string ConvertCP(string S)
        {
            Encoding cp866 = Encoding.GetEncoding(866);
            Encoding cp1251 = Encoding.Default;
            byte[] bufBytes = cp1251.GetBytes(S);
            bufBytes = Encoding.Convert(cp866, cp1251, bufBytes);
            S = cp1251.GetString(bufBytes);
            return S;
        }
Добавлено через 5 минут
Как я понял логику, то сначала мы определяем две кодировки - исходную и назначения, затем всю строку перегоняем в массив байт, причем (и в этом был изначальный затык) GetBytes() должна вызываться из назначения, потом конвертируем и возвращаем в строку.

Добавлено через 1 час 25 минут
ну и совсем наводя порядки в коде мы приходим к:
C#
1
2
        string ConvertCP(string S)
            return cp1251.GetString(Encoding.Convert(cp866, cp1251, cp1251.GetBytes(S)));
0
TheGreatCornholio
1227 / 708 / 282
Регистрация: 30.07.2015
Сообщений: 2,385
04.06.2018, 22:40 3
Цитата Сообщение от belalugoci Посмотреть сообщение
спасибо всем кто помогал
Всегда пожалуйста
Цитата Сообщение от belalugoci Посмотреть сообщение
конкретно dsquery.exe
Конкретно я, например, хз что это такое (загуглил разумеется) и как это запускать
(причем безопасно для себя и чтобы воспроизвести Вашу проблему).

Поэтому отсутствию ответов можно не удивляться.
0
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
05.06.2018, 04:14  [ТС] 4
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Конкретно я, например, хз что это такое (загуглил разумеется) и как это запускать
(причем безопасно для себя и чтобы воспроизвести Вашу проблему).
Поэтому отсутствию ответов можно не удивляться.
так проблема то не в том что запущено, запускайте что хотите: cmd, telnet, nslookup, ping и т.п. По коду как бы понятно, да и проблему я описал конкретно, так что я не верю в запутавшихся кодеров. Всё сводилось к опыту работы с Encoding и это тоже понятно из кода. А dsquery без наличия домена в сети вы не сможете использовать.
PS: вы серьезно не поняли что нужно из 866 перекодировать в 1251? Запустите cmd и выполните команды:
> c:
> mkdir test
> cd test
> ping ya.ru >a.txt
> start a.txt
У вас откроется окно блокнота, русский текст будет в кодировке 866 и вы увидите закорючки вместо русского текста (если у вас конечно винда не английская). Эта проблема существует ровно с тех пор, как Microsoft ушла от DOS кодировки, то есть почти 30 лет.
0
TheGreatCornholio
1227 / 708 / 282
Регистрация: 30.07.2015
Сообщений: 2,385
05.06.2018, 12:12 5
Лучший ответ Сообщение было отмечено belalugoci как решение

Решение

Цитата Сообщение от belalugoci Посмотреть сообщение
вы серьезно не поняли что нужно из 866 перекодировать в 1251?
Я всегда рассматриваю изначальную проблему как правило, а то что вы написали (попытка 866->1251) - это Ваш способ решения.
Способы решения ТС или клиента (когда работаю), я предпочитаю игнорировать в начале
Сначала стараюсь воспроизводить саму проблему, там уже смотрю что куда кого...

Цитата Сообщение от belalugoci Посмотреть сообщение
ну и совсем наводя порядки в коде мы приходим к:
Если уж совсем наводить порядки, просто добавь воды StartInfo.StandardOutputEncoding
C#
1
dcquery.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866);
1
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
05.06.2018, 13:10  [ТС] 6
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Я всегда рассматриваю изначальную проблему как правило
верно, изначальная проблема и была озвучена - перекодировка из окна консоли в поле Text. Но вы этого не заметили увлекшись изучением dsquery. Очевидно что ваш ответ "dcquery.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866);" и прозвучал бы сразу, как наставление на путь истинный, ибо он как раз показывает глупость моего выбора решения, обусловленную незнанием C# и действием по аналогии с Делфи, которым я был увлечен в начале 2000-х.

Цитата Сообщение от Woldemar89 Посмотреть сообщение
Если уж совсем наводить порядки, просто добавь воды StartInfo.StandardOutputEncoding
Спс. Это видимо дзен данного решения.

PS: мне простительно, я C# вижу только вторую неделю по выходным.
0
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
14.06.2018, 04:04  [ТС] 7
Дополню, конкретно для dsquery.exe есть ключ "-uco" который выводит результаты в Unicode, так что даже перекодирование не требуется.
0
TheGreatCornholio
1227 / 708 / 282
Регистрация: 30.07.2015
Сообщений: 2,385
14.06.2018, 08:42 8
Цитата Сообщение от belalugoci Посмотреть сообщение
Дополню, конкретно для dsquery.exe есть ключ "-uco" который выводит результаты в Unicode, так что даже перекодирование не требуется.
Ну а теперь перечитайте все, что выше и поймете, о чем я тут распинался
Проблема - это вывод и кракозябры.
А перекодировка на C# - это Ваш способ решения.
Будь у меня доступ к dsquery, Вы бы, вероятно, получили этот ответ плюс я шарп бы подправил.
0
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
14.06.2018, 08:59  [ТС] 9
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Будь у меня доступ к dsquery
https://docs.microsoft.com/en-... 32(v=ws.10)
вот ваш доступ к dsquery ))) не в доступе дело же.

я изначально не мог предположить что есть такой ключ, так как работая с cmd/ps ни разу на такое не натыкался, да и сейчас наткнулся случайно. подозреваю ms сама использует вывод dsquery в далеко не консольных приложениях, и чтобы не городить перекодировки просто сделали её один раз, но по ключу.
и я не против, что решение находится далеко не всегда в плоскости заданного вопроса.
0
TheGreatCornholio
1227 / 708 / 282
Регистрация: 30.07.2015
Сообщений: 2,385
14.06.2018, 09:03 10
Цитата Сообщение от belalugoci Посмотреть сообщение
не в доступе дело же.
Под доступом я имел ввиду - если бы эта хрень была под рукой и\или хотя бы было понятно что это из описания темы.
Цитата Сообщение от belalugoci Посмотреть сообщение
я изначально не мог предположить что есть такой ключ, так как работая с cmd/ps ни разу на такое не натыкался
Иногда наш опыт может сыграть с нами злую шутку, поэтому взгляд со стороны на проблему (а не на решение) часто очень помогает, даже профессионалам, которым опыт подсказывает "да так же не бывает".
0
Нарушитель
-64 / 95 / 15
Регистрация: 01.06.2018
Сообщений: 1,549
14.06.2018, 09:14  [ТС] 11
Цитата Сообщение от Woldemar89 Посмотреть сообщение
если бы эта хрень была под рукой и\или хотя бы было понятно что это из описания темы.
да не нужна она вам под рукой.
кроме dsquery я так же делаю вызовы других консольных команд и у них нет такого ключа, именно поэтому я написал "конкретно для dsquery" в конце темы.
Ваша помощь была универсальной для задания кодировки процесса и ей я и пользуюсь. Именно это и есть решение и оно соответствует начальной теме и моему запросу.

Цитата Сообщение от Woldemar89 Посмотреть сообщение
Иногда наш опыт может сыграть с нами злую шутку, поэтому взгляд со стороны на проблему (а не на решение) часто очень помогает, даже профессионалам, которым опыт подсказывает "да так же не бывает".
Я согласен с этим, но не в данном случае.

Тему перекодирования я, как незнающий c# выискивал в гугле, и тот код, которым я пытался сделать перекодировку просто взять из сети. У меня много вопросов было и я находил ответ на них в гугле на этом форуме, поэтому и зарегистрировался. И многие решения, здесь подсказанные как раз позволяют узнавать что-то в C# правильное, а не велосипедное. Но узнать новичку велосипед это или нет можно только после общения по теме, а тут (на форуме) есть некоторые личности, которые считают что обсуждать нечего.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.06.2018, 09:14

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Как в консоли в зависимости от размера окна заполнить строго до конца одну строчку определенными символами?
Например, Console.WriteLine("{0}", new string('-', 50));Если окно в ширину больше чем 50 символов,...

Создание окна в консоли
Как в консоли создать окно и потом выводить текст и считывать уже с этого окна? Чтобы было как на...

Расширение окна консоли
Доброго времени суток! Подскажите, пожалуйста, как расширить окно консоли. Не увеличить во весь...

Оформление чёрного окна консоли VS C++
Здравствуйте. Как в си ++ в чёрном окне сделатать следующее: Нужно сделать заливку синим цветом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.