Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для MallSerg
91 / 58 / 14
Регистрация: 16.11.2018
Сообщений: 274

Как приложение может ввести само себе на вход? что бы провернуть loop

04.08.2025, 23:51. Показов 1356. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть приложение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Threading;
 
namespace app4{
class Program {
public  static string        outmsg = "";
private static List<string>  lines  = new List<string>();
private static bool          loop   = true;
private static Form          tForm;
private static Thread        thread;
    
public static void Command (){
    switch (lines[0]) {
        case "show":
            tForm.Invoke((Action)(() => tForm.Show()));
            break;
        case "hide":
            tForm.Invoke((Action)(() => tForm.Hide()));
            break;
        case "exit":
            loop = false;
            break;
        case "Aut":
            lines.ForEach( P => Program.outmsg += P + "\n" );
            break;
    }
}
public static void Main(string[] _args){
  string line = "";    
  tForm = new TestForm();
  thread = new Thread(() => Application.Run(tForm));
  thread.SetApartmentState(ApartmentState.STA); 
  thread.Start();
  
while (loop){
    if ( outmsg != ""  ) {
        Console.Write( outmsg );
        outmsg = "";
    }
    line = Console.ReadLine();
    switch (line) {
        case "COMMAND BEGIN":   
            lines.Clear();  
            break;
        case "COMMAND END":     
            Command() ;     
            break;
        default:                
            lines.Add(line);    
            break;
    }
}
  tForm.Invoke((Action)(() => tForm.Close()));
  thread.Join();
}
}
}
Преамбула: Есть древнющее приложение из 90х годов прошлого века и есть желание исправить его функционал с помощью C# для этих целей была написана DLL которая аттачится к этому приложению и перехватывает его стандартные потоки ввода вывода.
древнющее приложение -> поток вывода -> DLL -> C# программа -> DLL -> поток ввода -> древнющее приложение.
Все работает Но ... C# программа, висит на строке «line = Console.ReadLine();» (пока это некрасиво решается таймером DLL долбит вход пустой строкой проворачивая loop).
Программа запускает отдельный тред в котором крутяться UI формы и прочее.
Вопрос:
Как из соседнего треда приложения провернуть loop что бы заполнить stdout(буфер C# приложения) ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.08.2025, 23:51
Ответы с готовыми решениями:

Как задать произвольное окончание строки (само-ход, само-свал, само-идентификация)?
делаю словарь нецензурных слов, сам словарь решил делать так: List&lt;string&gt; salmons = new...

Мне нужно, чтобы пробелы до запятых тоже удалялись, никак не могу додумать как это можно провернуть
string text = &quot;По правилу расстановки ,знаки препинания,бегут,перед каждым знаком ,препинания...

Отправить запрос, а потом с результатом провернуть действия
Суть: отправить в БД запрос SELECT name FROM characters WHERE online=1 ответ должен прийти в...

7
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
05.08.2025, 02:09

Не по теме:

Жееееееееееееееееееесть..... ЭЖР-Д, Белая электролитического лужения, Код ОКП 11 1510



Окей, для начала я бы выносил в отдельные поток не форму, а ваш while (loop)

Далее, т.к. Console.ReadLine это обёртка над TextReader, стоит использовать Console.In.ReadLineAsync, который позволят задействовать токен отмены.
0
 Аватар для MallSerg
91 / 58 / 14
Регистрация: 16.11.2018
Сообщений: 274
05.08.2025, 08:36  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Окей, для начала я бы выносил в отдельные поток не форму, а ваш while (loop)
Отдельный поток и форма это частный случай.

Идея была в том что бы приложение при чтении из свой файловой БД в ответ получало и цирк с конями и блекджек с куртизанками без привязки к какому то конкретному приложению. DLL просто вызывает "CreateProcessA(...)" и не так важно что это C#, python, JS, или PHP в общем все что умеет считывать и записывать в консоль.
т.е. хотелось бы оставить логику что loop крутится в и обрабатывает запросы в основном потоки а вспомогательные потоки запускались бы по мере необходимости. Это позволит писать обычные консольные приложения ввёл-вывел.

В голову пока приходит тока экспорт из DLL функции которая провернет loop пару строчек и должно работать.

В идеале хотелось бы что бы был метод - Console.In.Write() а там тока 50 способов как прочитать байты потока =(.
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,766
05.08.2025, 13:36
Цитата Сообщение от MallSerg Посмотреть сообщение
древнющее приложение -> поток вывода -> DLL -> C# программа -> DLL -> поток ввода -> древнющее приложение.
А вариант просто запустить "древнющее приложение" напрямую из C#-программы через new Process(<..>).Start(), перенаправив ввод/вывод флагами 'RedirectStandard[Input|Output]" и "RedirectStandardError" не срабатывает?

При этом считывать данные из потоков 'Output/Error' можно ассинхронно через события 'OutputDataReceived' и 'ErrorDataReceived'.
0
 Аватар для MallSerg
91 / 58 / 14
Регистрация: 16.11.2018
Сообщений: 274
05.08.2025, 20:53  [ТС]
Цитата Сообщение от kotelok Посмотреть сообщение
А вариант просто запустить "древнющее приложение" напрямую из C#-программы через new Process(<..>).Start(), перенаправив ввод/вывод флагами 'RedirectStandard[Input|Output]" и "RedirectStandardError" не срабатывает?
В этом нет смысла т.к. древнее приложение не использует свои собственные stdIn stdOut. Обычная графическая программа оно создает новые подключения к именованном каналам с помощью обычного openFile из winapi. И уже эти новые свежесозданные потоки древнего приложения DLL перенаправляет в приложение на C# на stdIn stdOut консольного приложения.

В целом приложение на C# работает так как требуется и как и подобает приличной программе ... не жгет электричество в вечном цикле и не генерирует никому не нужных событий, обработчиков, данных. Просто ожидает данных для обработки или вывода информации.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
06.08.2025, 01:25
Цитата Сообщение от MallSerg Посмотреть сообщение
Отдельный поток и форма это частный случай.
Ваше приложение всегда запускает форму. Я бы собирал проект как WinExe, чтобы 100% понимать что это НЕ консоль, а дектопное приложение, в котором UI отображается не так часто. К сожалению там нужно сначала "активировать" поток ввода-вывода, так что писанины больше.

Можете оставить как есть, сильно погоды это не делает.

Цитата Сообщение от MallSerg Посмотреть сообщение
В идеале хотелось бы что бы был метод - Console.In.Write() а там тока 50 способов как прочитать байты потока =(.
Я из всех сообщений так и не собрал полную картину, но что вижу у вас:
- цикл while, который штудирует bool. В целом норм, но конкретно тут стоит использовать CancelationToken в любом случае, почему -- долго объяснять.
- Console.ReadLine -- не проверяет на null. Если поток ввода закрыли, то это означает конец ввода. Больше ничего и никогда не прилетит, а значит ваше приложение будет крутится вечность, при этом выгружая CPU.
- Console.ReadLine -- синхронный и его нельзя прервать извне, например по закрытию формы. А вот Console.In.ReadLineAsync уже можно, при использовании CancelationToken.
- Нет Flush после Write. Ваш текст может висеть в буфере до конца жизни приложения.

Я бы ещё пнул за архитектурные решения связанные с static и outmsg.

Базово как-то так (я бы ещё накинул кода, но без понимания "зачем" оно вам не нужно)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    class Program
    {
        public static void Main(string[] _args)
        {
            using var cts = new CancellationTokenSource();
            var token = cts.Token;
            TestForm form = default!;
            void ShowForm() => form.Invoke(() => form.Show());
            void HideForm() => form.Invoke(() => form.Hide());
 
            #region form
 
            var formThread = new Thread(() =>
            {
                form = new TestForm();
                form.FormClosed += (_, __) => cts.Cancel(); // либо нужно запретить закрывать форму, пока активен out|in
                token.Register(() => form.BeginInvoke(() => form.Close()));
                //ApplicationConfiguration.Initialize(); // под вопросом
                Application.Run(form);
            });
            formThread.SetApartmentState(ApartmentState.STA);
            formThread.Start();
 
            #endregion
 
            #region out|in
 
            var outinTask = Task.Run(async () =>
            {
                var lines = new List<string>();
                void PrintLines()
                {
                    lines.ForEach(p => Console.WriteLine(p));
                    Console.Out.Flush();
                }
 
                var handlers = new Dictionary<string, Action>()
                {
                    { "show", ShowForm },
                    { "hide", HideForm },
                    { "exit", cts.Cancel },
                    { "Aut", PrintLines }
                };
 
                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        var line = await Console.In.ReadLineAsync(token);
                        // признак того что нам закрыли поток, если не выйдем, цикл будет молотить вечность
                        if (line is null)
                            return;
 
                        switch (line)
                        {
                            // проверка что COMMAND BEGIN не задублировано не нужна?
                            case "COMMAND BEGIN":
                                lines.Clear();
                                break;
                            case "COMMAND END":
                                // берём первый элемент списка, если он существуем по нему ищем команду в словаре и пинаем
                                if (lines is [var command, ..] && handlers.TryGetValue(command, out var handler))
                                    handler();
                                break;
                            default:
                                lines.Add(line);
                                break;
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    // проверяем что именно отмена нашей операции, а не что-то иное
                    if (!token.IsCancellationRequested)
                        throw;
                }
            });
 
            #endregion
 
            outinTask.Wait();
            formThread.Join();
        }
    }
Возможно причина ваших проблем в другом, но рекомендую разобрать сначала приведённый код.
0
 Аватар для MallSerg
91 / 58 / 14
Регистрация: 16.11.2018
Сообщений: 274
06.08.2025, 08:32  [ТС]
Цитата Сообщение от MallSerg Посмотреть сообщение
Как приложение может ввести само себе на вход?
Кстати по теме темы.
Можно получить собственный процесс приложения
process = System.Diagnostics.Process.GetCurrentPro cess();
И уже у процесса
process.StandardInput.WriteLine ("чета там");

Но как я понимаю нельзя одеть тапки в которых кто то уже ходит т.е. если кто то уже открыл процесс/поток/файл то попытка писать в него из другого приложения вызовет исключение.

В строках не просто команды там еще и параметры к командам, чета вроде

Code
1
2
3
4
5
6
COMMAND BEGIN
GetData
01.06.2025
30.06.2025
*.PDF
COMMAND END
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
06.08.2025, 12:29
Цитата Сообщение от MallSerg Посмотреть сообщение
Можно получить собственный процесс приложения

Не по теме:

Мне каждый раз так хочеться очень грязно пошутить по этому поводу, но получать бан очень не охота....


Перед вами стоит куллер с водой на кухне.

Нормальный программист: берёт чашку, наливает воду, пьет.
Программист который получает self-process для работы с out|in: берёт чайник, наливает воду в него, берёт чашку, наливает воду из чайника и только потом пьет.

Работайте с Console и не чудите.

Цитата Сообщение от MallSerg Посмотреть сообщение
В строках не просто команды там еще и параметры к командам, чета вроде
Вообще фиолетово. Обработчик строк может быть любой, хоть на json переключать в процессе.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.08.2025, 12:29
Помогаю со студенческими работами здесь

Как скрипт может сохранить массив, в случае если ему нужнон вызвать самого себя?
Итак проблема: Скрипт (поисковый движок) вызывает сам себя для того, чтобы отобразить последующие...

Как можно сделать, чтобы checkbox сам себя отметил, при сравнение вводимого текста?
не нашел нигде об этом информации и сам не особо шарю, но делаю задание с ардуино и меткой nfc. и...

Нужно, чтобы приложение могло само себя обновлять
Мне нужно было, чтобы приложение могло само себя обновлять (1 .exe файл). Пробовал через технологию...

Приложение обновляет само себя
Всем привет! Имеется патчер, который сравнивает по имени файла хеш md5 папки клиента со списком...

bindingsource не может быть источником данных для самого себя
Здравствуйте друзья. Я цыклом пропинговываю ip адреса, беру ip из базы (access). Выскакивают...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3, Box2D, FreeType и SDL3_ttf из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru