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

  • Автор темы [m7]Zeitgeist
  • Дата начала
Статус
Закрыто для дальнейших ответов.
M

[m7]Zeitgeist

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

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

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

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

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

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

Для курсавой!
 
B

Barmutik

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

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

[m7]Zeitgeist

#3
<!--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]


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

Barmutik

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

Код:
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...
 
I

IronBOSS

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

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

[m7]Zeitgeist

#6
<!--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 заранее сенкс тока справку по функциям приложи))!
 
M

MegaDiablo

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

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

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

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

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

Alex Death

#8
А как вводить выводить через чужую консоль?
 
M

MegaDiablo

#9
А как вводить выводить через чужую консоль?
Не понял твоего вопроса. Нельзяли более подробно написать, что ты хочешь сделать.

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

Alex Death

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

mikola1

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

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


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

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

Код:
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;
 
Статус
Закрыто для дальнейших ответов.