Форум » GUI » Как передать данные из одной программы в другую ? » Ответить

Как передать данные из одной программы в другую ?

Andrey: Всем привет... Есть ли механизм передачи данных между программами ? Допустим прога на МиниГуи запустила терминалку. Как узнать что терминалка нормально запустилась ?

Ответов - 59, стр: 1 2 3 All

PSP: Механизм mutex-ов

Andrey: А пример можно для Харбора как это будет работать ? А то по описанию трудно понять как это делать... Когда с этим работаешь, то понятно... а когда не знаешь как использовать, то труба !

Andrey: Нашел на Дельфи: Дело в том, что можно в памяти создавать временные файлы. При перезагрузке они теряются, а так существуют. Кстати, этот метод можно использовать и для обмена информацией между вашими приложениями. Пример с использованием FileMapping: program Project1; uses Windows, // Обязательно Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} const MemFileSize = 1024; MemFileName = 'one_inst_demo_memfile'; var MemHnd : HWND; begin // Попытаемся создать файл в памяти MemHnd := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READWRITE, 0, MemFileSize, MemFileName); // Если файл не существовал запускаем приложение if GetLastError<>ERROR_ALREADY_EXISTS then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; CloseHandle(MemHnd); end. А как бы сделать похожее на МиниГуи ?

vvv: А если просто создавать временный файл на диске?

Andrey: vvv пишет: А если просто создавать временный файл на диске? Ну это будет слишком просто и непонятно.... Прога на МиниГуи (вывесила заставку ЗАПУСКАЮ....), далее запустила терминалку на хХарборе, терминалка на хХарборе создала временный файл "все'Ok". Далее прога на МиниГуи у себя отметила что прога на хХарборе запустилась нормально, убрала заставку ЗАПУСКА (как сделать пока не представляю)... Потом нужно рассматривать варианты, если программа не запустилась по каким то причинам... кто будет убирать заставку и когда ? И т.д.

santy: Есть интересный пример : http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx

Andrey: santy пишет: Есть интересный пример Спасибо. Только в С я не силен. Как бы на Харборе сделать ?

SergKis: Andrey пишет: Прога на МиниГуи (вывесила заставку ЗАПУСКАЮ....), далее запустила терминалку на хХарборе, терминалка на хХарборе создала временный файл "все'Ok". Далее прога на МиниГуи у себя отметила что прога на хХарборе запустилась нормально, убрала заставку ЗАПУСКА (как сделать пока не представляю)... Потом нужно рассматривать варианты, если программа не запустилась по каким то причинам... кто будет убирать заставку и когда ? И т.д. Вот примерный ответ (не C и hb) на AutoIt3: [pre2] ; Запуск AutoIt3.exe <ScriptName.au3> ; В AutoIt3 есть возможность собирать из скрипта Exe, включая в него файлы, ; как при инсталяции. ; http://autoit-script.ru/ #NoTrayIcon $jpg = ".\images\darkside.jpg" ; Создать всплывающее окно с изображением. по умолчанию в центре экрана ; SplashImageOn("title", "file" [, width] [, height] [, x pos] [, y pos] [, opt]) ; file - Полный путь к файлу с изображением (BMP, GIF или JPG). SplashImageOn("Splash Screen", $jpg, 150, 150) ; Инициализировать набор пользовательских реквизитов для выполнения ; Run и RunWait операций. Только для 2000/XP и позже. ; If RunAsSet("Administrator", @Computername, "adminpassword") Then ; Run("MyProg.exe MyParam", "WorkingDir") ; снять набор пользовательских реквизитов ; RunAsSet() ; EndIf Run("MyProg.exe MyParam", "WorkingDir") ; Прервать выполнение скрипта до момента появления указанного окна. ; WinWait ( "title", ["text"], [timeout] ) ; или ; Прервать выполнение скрипта до момента активизации указанного окна. ; timeout в секундах ; WinWaitActive ( "title", ["text"], [timeout] ) If WinWaitActive( "MyProgramTitle", "", 30 ) Then MsgBox(1, "Info", "MyProgram started", 10) ; timeout 10 сек. Else MsgBox(1, "Info", "Failed started", 10) ; timeout 10 сек. ; Принудительно закрыть окно. ; WinKill ( "title", ["text"] ) ; или ; Остановить выполнение указанного процесса. ; ProcessClose ( "process" [, flag] ) ; Названия процессов могут быть, например, "notepad.exe", "winword.exe". EndIf ; Закрыть окна, открытые с помощью SplashTextOn или SplashImageOn. SplashOff() [/pre2]

vvv: Андрей, а какой командой запускаешь терминалку?

Andrey: vvv пишет: Андрей, а какой командой запускаешь терминалку? ShellExecute(, 'open',cPathExe+cRunExe, cParam, "" , SW_SHOWNORMAL)

Andrey: Возвращаюсь опять к этому вопросу. Уже много времени прошло. В прошлом году для обмена между МиниГуи и терминалкой сделал (с помощью форумчан) пример: MiniGUI\SAMPLES\BASIC\COMM_2 Вроде отлично работал, пока пути без русских букв. Реализовал передачу данных всё таки через базу по таймеру. Сейчас хочу переделать. Нужно передавать данные между двумя программами (своими) на одном компе. Можно ли использовать стандартный SendMessage() ? Основная программа (сервер) на МиниГуи, клиент терминалка. В клиенте правятся записи базы, после редактирования SendMessage() и эти номера записей принимает сервер. Какова вероятность потери при передачи с SendMessage() ? И ещё при взаимодействии с другими программами (допустим на С#) сколько можно передать данных ? Т.е. какой максимальный размер данных при передачи через SendMessage() ?

SergKis: Andrey пишет Сейчас хочу переделать. С терминалкой, не очень будет, с wvt можно через WM_COPYDATA Проще сделать через переменную(е) Enviroment (вроде до 4К), т.е. hb_SetEnv(..., ...) hb_GetEnv(...)

Andrey: SergKis пишет: С терминалкой, не очень будет, с wvt можно через WM_COPYDATA У меня терминалка с wvt. Тест с C# идёт, c терминалкой нет. P.S. Нашел вот тут нужную тему: Передача сообщений между приложениями/процессами при помощи сообщения WM_COPYDATA http://www.frolov-lib.ru/books/bsp/v27/ch2_2.htm Минигуи сделал, работает. А терминалку нет. Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() ? Саму функцию взял из МиниГуи - [pre2]#pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #ifndef __XHARBOUR__ #define ISBYREF( n ) HB_ISBYREF( n ) #endif HB_FUNC( SENDCOPYDATAMSG ) { HWND hwnd; COPYDATASTRUCT cds; hwnd = (HWND) hb_parnl( 1 ); cds.dwData = 0xCE98; cds.lpData = (char *) hb_parc( 2 ); cds.cbData = strlen( (char*) cds.lpData ); SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM) &cds ); } #pragma ENDDUMP [/pre2]

SergKis: Andrey пишет Как в терминалке прикрутить передачу 1. Надо залезть в исходники, добавить обработку WM_COPYDATA, прочитать получ. данные, сохранив в буф. и послать какой то KeyBoadrd 2. Иметь процедуру, которая сможет получить данные из буф. ( HB_FUNC ) 3. Сделать SET KEY на KeyBoard процедуры из 2., которая примет полученные данные как то так

Петр: Andrey пишет: Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() ? SergKis пишет: 1. Надо залезть в исходники Или я не вижу всех сообщений, или вы издеваетесь друг над другом..

SergKis: Петр И в чем протеворечие ? Andrey про МиниГуишный вариант, я про wvt-ый (принять по WM_COPYDATA). Возможно у Вас есть решение, но это уже др. история\предложение.

Петр: SergKis пишет: И в чем протеворечие ? Нет противоречий, но.. Andrey пишет: Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() похоже на тонкий троллинг публики. А с вашей стороны рекомендации по организации прийома с использованием какого-то KeyBoadrd, наводят меня на мысль, что я что-то пропустил или не понял. Процесс организации прийома описан правильно, ну чуть усложнили.. Но последний вопрос был про передачу! А рекомендации на эту тему Андрею я давал. Что-то вроде используйте то, что знаете и умеете. Стандартов нет - варианты есть, тем более если все размещено локально. И еще, если Андрей написал сервер, то обычно сервер работает по какому-то протоколу - пускай его и использует для взаимодействия. Я уже не говорю, что "времени прошло много" и с терминалки можно было спрыгнуть. Но это лень, мне знакомо это святое чувство

Andrey: Петр пишет: Я уже не говорю, что "времени прошло много" и с терминалки можно было спрыгнуть. Но это лень, мне знакомо это святое чувство Ага. С удовольствием бы спрыгнул. Третий год АКТИВНО переделываю проект. Бровсом только год занимаюсь. Без поддержки с форума не смог бы столько сделать. БОЛЬШОЕ ВАМ ВСЕМ СПАСИБО, кто помогал мне ! Конец работы уже виден, но столько ещё делать.... А юзера новую прогу и не жалуют. Перевести на новую программу одна морока. Как привыкли работать, так и всё. Юзера не любят осваивать новое. Не знаю что с ними делать... Разобрался я с Передачей сообщений между приложениями. В качестве обучающего примера выслал Григорию для включения в библиотеку. Передача строки идёт на ура ! И даже ехе-ник в 700Мб передаю и получаю !!! Всё глотает. Пробовал через C# передать строку в 50Мб - проходит, т.е. Минигуи такую строку тоже принимает. Но сборщик МУСОРА в С# хуже чем в Харборе (это не моё мнение). Теперь можно реализовать по событию контроль за изменением записей в базе между двумя программами и обходиться без таймера.

SergKis: Петр пишет похоже на тонкий троллинг публики Это не троллинг, что в данный момент Андрею надо, то он и говорит прямо, честно и откровенно. Правда, потом оказывается, надо еще воз и тележку и не маленькую ..., потому я сразу про wvt прием и говорил. Процесс организации прийома описан правильно, ну чуть усложнили.. В чем ? Сейчас это уже не использую (в hb 2.0 было), но интересно, если проще можно.

Петр: SergKis пишет: В чем ? Сейчас это уже не использую (в hb 2.0 было), но интересно, если проще можно. По пунктам 1. Надо залезть в исходники, добавить обработку WM_COPYDATA, прочитать получ. данные, сохранив в буф. и послать какой то KeyBoadrd Не обязательно. Нужно заменить стандартный обработчик окна. Это можно делать и что назывется "на лету". KeyBoard зачем трогать? 2. Иметь процедуру, которая сможет получить данные из буф. ( HB_FUNC ) Все зависит от пункта №1. Все действие можно перевести и на PRG уровень. 3. Сделать SET KEY на KeyBoard процедуры из 2., которая примет полученные данные как то так Опять же вы использовали существующий механизм, а без этого можно обойтись. На PRG уровне вы создаете публичную переменную (масив строк, хаш) и по событию WM_COPYDATA ваш обработчик добавляет в переменную элементы. Вам остается контролировать состояние переменной (используя таймер, потоки, возможности hb_idle * - то, что у вас лучше всего получается) и вовремя удалять отработанные данные. В качестве переменной может быть экземпляр какого-то класса с методами и свойствами. Я надеюсь, что Андрей организовал хоть какую-то проверку целосности данных. Если бы речь о 2-х MiniGUI программах, то там вообще "рай": мультипоточность (в разумных пределах, MiniGUI не thread safe), сериализация/десериализация переменных простых типов, выбор методов проверки контрольных сум. Я надеюсь, что пример Андрея будет именно таким



полная версия страницы