Возможность компиляции исходника...

Тема в разделе "Delphi - Система", создана пользователем [m7]Zeitgeist, 11 фев 2006.

Статус темы:
Закрыта.
  1. [m7]Zeitgeist

    [m7]Zeitgeist Гость

    Cуществует ли возможность реализовать это: "Компиляция исходников непосредственно из среды редактора внешними компиляторами(pascal (TP) либо консольного кампилятора Delphi)";на Delphi!

    Задача такова:
    1) Есть чтото на подобии текстового редактора RichEdit(MEMO)и кнопка кампилировать!

    2) При нажатии на кнопку происходит компиляция исходника и выполнение программы; если к примеру существует ошибка то редактор должен либо подсвитить строку с ошибкой либо вывести в Memo либо Check List Box.

    3) Результат выводиться В Memo

    Может ктонить сталкивался с данными исходниками или статьями на эту тему!

    Главное это реализация взаимодействия с внешним компилятором!

    Для курсавой!
     
  2. Barmutik

    Barmutik Гость

    Да вообщем-то ничего сильно сложного нет ...

    - пишите исходный текст
    - сохраняете в файл
    - натравливаете борляндовский компилятор командной строки
    - перехватываете вывод сообщений
    - показываете сообщения в нужном Вам контроле...
     
  3. [m7]Zeitgeist

    [m7]Zeitgeist Гость

    <!--QuoteBegin-Barmutik+13:02:2006, 09:14 -->
    <span class="vbquote">(Barmutik @ 13:02:2006, 09:14 )</span><!--QuoteEBegin-->Да вообщем-то ничего сильно сложного нет ...

    - пишите исходный текст
    - сохраняете в файл
    - натравливаете борляндовский компилятор командной строки
    - перехватываете вывод сообщений
    - показываете сообщения в нужном Вам контроле...
    [snapback]30526" rel="nofollow" target="_blank[/snapback]​
    [/quote]


    А как перехватить вывод сообщений может быть подскажите документацию или статейку на данную тему
     
  4. Barmutik

    Barmutik Гость

    Вот пример...

    Код (Text):
    const
    RETURN_INVALID_HANDLE = MaxInt;
    RETURN_EXECUTE_FAILED = MaxInt - 1;


    function ExecuteWait(Command, Params: string; ShowWindow: Word;
    Output: TStrings): Cardinal;


      function GetTempFile: string;
      var
       bFile, bDir: Array [0..255] of char;
      begin
       GetTempPath(SizeOf(bDir), bDir);
       GetTempFileName(bDir, 'tmp', 0, bFile);
       Result := bFile;
      end;


    var
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    SecurityAttr: TSecurityAttributes;
    hOut: THandle;
    tempfile: string;
    workingdir: PChar;
    begin
    ZeroMemory(@StartupInfo, SizeOf(TStartupInfo));
    ZeroMemory(@ProcessInfo, SizeOf(TProcessInformation));
    ZeroMemory(@SecurityAttr, SizeOf(TSecurityAttributes));


    tempfile := GetTempFile;


    with SecurityAttr do begin
     nLength := SizeOf(TSecurityAttributes);
     lpSecurityDescriptor := nil;
     bInheritHandle := True;
     end;


    hOut := CreateFile(PChar(tempfile), GENERIC_READ or GENERIC_WRITE, 0,
    @SecurityAttr,
              CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0);


    if hOut = INVALID_HANDLE_VALUE then
     Result := RETURN_INVALID_HANDLE
    else begin
     with StartupInfo do begin
      cb := SizeOf(TStartupInfo);
      wShowWindow := ShowWindow;
      dwFlags := STARTF_USESHOWWINDOW;
      if Assigned(Output) then begin
       hStdOutput := hOut;
       hStdError := hOut;
       hStdInput := GetStdHandle(STD_INPUT_HANDLE);
       dwFlags := dwFlags or STARTF_USESTDHANDLES;
       end;
      end;


     if ExtractFilePath(Command) <> '' then
      workingdir := PChar(ExtractFilePath(Command))
     else
      workingdir := nil;


     if Pos(' ', Command) <> 0 then Command := '"' + Command + '"';


     if CreateProcess(nil, PChar(Command + ' ' + Params), nil, nil, True, 0,
    nil,
              workingdir, StartupInfo, ProcessInfo) then begin
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      GetExitCodeProcess(ProcessInfo.hProcess, Result);
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(hOut);
      if Assigned(Output) then Output.LoadFromFile(tempfile);
      DeleteFile(tempfile);
      end
     else begin
      CloseHandle(hOut);
      DeleteFile(tempfile);
      Result := RETURN_EXECUTE_FAILED;
      end;
     end;


    end;

    Так же можете поискать компонент TRedirector...
     
  5. IronBOSS

    IronBOSS Гость

    Да и я думал зделать к TASM свой IDE.
    Всегда по возможности хочу свой soft использовать.
    У меня и специальная DLL для этого.
    Думал как зделать бы, что если в исходнике ощибка на каком та строке тогда читаем вывод TASM-а (как малый parser), он показывает номер и описание ощибки тогда перемещаем курсор в это место.

    Вот такая идея у меня но пока хочу свой Mediaplayer закончить.
    Тогда попробую.
    Еслй нужна эта DLL, то кричи :(
     
  6. [m7]Zeitgeist

    [m7]Zeitgeist Гость

    <!--QuoteBegin-IronBOSS+19:02:2006, 09:30 -->
    <span class="vbquote">(IronBOSS @ 19:02:2006, 09:30 )</span><!--QuoteEBegin-->Да и я думал зделать к TASM свой IDE.
    Всегда по возможности хочу свой soft использовать.
    У меня и специальная DLL для этого.
    Думал как зделать бы, что если в исходнике ощибка на каком та строке тогда читаем вывод TASM-а (как малый parser), он показывает номер и описание ощибки тогда перемещаем курсор в это место.

    Вот такая идея у меня но пока хочу свой Mediaplayer закончить.
    Тогда попробую.
    Еслй нужна эта DLL, то кричи :(
    [snapback]30806" rel="nofollow" target="_blank[/snapback]​
    [/quote]

    Кидай в личку либо на zeit[tm]nebo.by заранее сенкс тока справку по функциям приложи))!
     
  7. MegaDiablo

    MegaDiablo Гость

    Люди если вам интересно как перехватить сообщение компилятора которое выводится на экран, то это просто и пишется так:

    Запускаете программу с параметрами и в конце строки с параметрами пишете "> имя файла".

    Вот как это будет выглядить

    dcc32.exe start.dpr >compile.$$$

    в файле compile.$$$ будет всё, что программа вывела на экран.
     
  8. Alex Death

    Alex Death Гость

    А как вводить выводить через чужую консоль?
     
  9. MegaDiablo

    MegaDiablo Гость

    Не понял твоего вопроса. Нельзяли более подробно написать, что ты хочешь сделать.

    Может и помогу, если смогу. :)
     
  10. Alex Death

    Alex Death Гость

    Например в системе открыта какаято консоль, как мне (чужой программе) писать и читать в нее (из нее)?
     
  11. mikola1

    mikola1 Гость

    Pipe

    Запуск программ с передачей консольного ввода и чтением вывода
    --------------------------------------------------------------------------------


    Автор: Алексей Бойко
    WEB-сайт: http://www.sources.ru

    Это пример запуска консольных программ с передачей ей консольного ввода (как если бы он был введен с клавиатуры после запуска программы) и чтением консольного вывода. Таким способом можно запускать например стандартный виндовый ftp.exe (в невидимом окне) и тем самым отказаться от использования специализированных, зачастую глючных компонент.

    Код (Text):
    function ExecuteFile(FileName, StdInput: string;
    TimeOut: integer;
    var StdOutput: string): boolean;

    label
    Error;

    type
    TPipeHandles = (IN_WRITE, IN_READ,
    OUT_WRITE, OUT_READ,
    ERR_WRITE, ERR_READ);

    type
    TPipeArray = array[TPipeHandles] of THandle;

    var
    i: integer;
    ph: TPipeHandles;
    sa: TSecurityAttributes;
    Pipes: TPipeArray;
    StartInf: TStartupInfo;
    ProcInf: TProcessInformation;
    Buf: array[0..1024] of byte;
    TimeStart: TDateTime;

    function ReadOutput: string;
    var
    i: integer;
    s: string;
    BytesRead: longint;

    begin
    Result := '';
    repeat

    Buf[0] := 26;
    WriteFile(Pipes[OUT_WRITE], Buf, 1, BytesRead, nil);
    if ReadFile(Pipes[OUT_READ], Buf, 1024, BytesRead, nil) then
    begin
    if BytesRead > 0 then
    begin
    buf[BytesRead] := 0;
    s := StrPas(@Buf[0]);
    i := Pos(#26, s);
    if i > 0 then
    s := copy(s, 1, i - 1);
    Result := Result + s;
    end;
    end;

    if BytesRead1024 then
    break;
    until false;
    end;

    begin
    Result := false;
    for ph := Low(TPipeHandles) to High(TPipeHandles) do
    Pipes[ph] := INVALID_HANDLE_VALUE;

    // Создаем пайпы
    sa.nLength := sizeof(sa);
    sa.bInheritHandle := TRUE;
    sa.lpSecurityDescriptor := nil;

    if not CreatePipe(Pipes[IN_READ], Pipes[IN_WRITE], @sa, 0) then
    goto Error;
    if not CreatePipe(Pipes[OUT_READ], Pipes[OUT_WRITE], @sa, 0) then
    goto Error;
    if not CreatePipe(Pipes[ERR_READ], Pipes[ERR_WRITE], @sa, 0) then
    goto Error;

    // Пишем StdIn
    StrPCopy(@Buf[0], stdInput + ^Z);
    WriteFile(Pipes[IN_WRITE], Buf, Length(stdInput), i, nil);

    // Хендл записи в StdIn надо закрыть - иначе выполняемая программа
    // может не прочитать или прочитать не весь StdIn.

    CloseHandle(Pipes[IN_WRITE]);

    Pipes[IN_WRITE] := INVALID_HANDLE_VALUE;

    FillChar(StartInf, sizeof(TStartupInfo), 0);
    StartInf.cb := sizeof(TStartupInfo);
    StartInf.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

    StartInf.wShowWindow := SW_SHOW; // SW_HIDE если надо запустить невидимо

    StartInf.hStdInput := Pipes[IN_READ];
    StartInf.hStdOutput := Pipes[OUT_WRITE];
    StartInf.hStdError := Pipes[ERR_WRITE];

    if not CreateProcess(nil, PChar(FileName), nil,
    nil, True, NORMAL_PRIORITY_CLASS,
    nil, nil, StartInf, ProcInf) then
    goto Error;

    TimeStart := Now;

    repeat
    Application.ProcessMessages;
    i := WaitForSingleObject(ProcInf.hProcess, 100);
    if i = WAIT_OBJECT_0 then
    break;
    if (Now - TimeStart) * SecsPerDay > TimeOut then
    break;
    until false;

    if iWAIT_OBJECT_0 then
    goto Error;
    StdOutput := ReadOutput;

    for ph := Low(TPipeHandles) to High(TPipeHandles) do
    if Pipes[ph]INVALID_HANDLE_VALUE then
    CloseHandle(Pipes[ph]);

    CloseHandle(ProcInf.hProcess);
    CloseHandle(ProcInf.hThread);
    Result := true;
    Exit;

    Error:

    if ProcInf.hProcessINVALID_HANDLE_VALUE then

    begin
    CloseHandle(ProcInf.hThread);
    i := WaitForSingleObject(ProcInf.hProcess, 1000);
    CloseHandle(ProcInf.hProcess);
    if iWAIT_OBJECT_0 then

    begin
    ProcInf.hProcess := OpenProcess(PROCESS_TERMINATE,
    FALSE,
    ProcInf.dwProcessId);

    if ProcInf.hProcess 0 then
    begin
    TerminateProcess(ProcInf.hProcess, 0);
    CloseHandle(ProcInf.hProcess);
    end;
    end;
    end;

    for ph := Low(TPipeHandles) to High(TPipeHandles) do
    if Pipes[ph]INVALID_HANDLE_VALUE then
    CloseHandle(Pipes[ph]);

    end;
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей