unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

  procedure RunSignleFile(AFileName: String); export; stdcall;
  procedure RunAllFile(AllFile, SelectedFile: string); export; stdcall;


implementation

uses
  ShellAPI, Registry, StrUtils, Envionment;

const
  SLinsenaStudyKey = 'SOFTWARE\Borland\Delphi\7.0';

  SIniFile = 'study.ini';
  SSectionName = 'Runner';


function GetDatabaseFilePath: string;
var
  Registry: TRegistry;
begin
  Result := '';
  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_LOCAL_MACHINE;
    if Registry.KeyExists(SLinsenaStudyKey) then
    begin
      if Registry.OpenKey(SLinsenaStudyKey, True) then
      begin
        Result := Registry.ReadString('RootDir');
      end;
    end;
  finally
    Registry.Free;
  end;
end;  

function GetCompiler(AType: string): string;
var
  objIni: TIni;  
  ModuleName, sFile: string;
begin
  SetLength(ModuleName, 255);
  GetModuleFileName(HInstance, PChar(ModuleName), Length(ModuleName));
  sFile := ExtractFilePath(PChar(ModuleName)) + SIniFile;
  objIni := TIni.Create(sFile);
  objIni.SectionName := SSectionName;
  objIni.DefaultString := '';
  Result := objIni.SValue[AType];
  objIni.Free;
end;  

procedure RunJava(AFileName: string);
var
  sFilePath: string;
  sFileName: string;
  lstBat: TStrings;
begin
  sFilePath := ExtractFileDir(AFileName);
  sFileName := ExtractFileName(AFileName);

  SetCurrentDir(sFilePath);
  lstBat := TStringList.Create;
  try
    lstBat.Add('set classpath=' + sFilePath + ';');
//    lstBat.Add('javac.exe ' + sFilePath + '\' + sFileName);
    lstBat.Add('javac.exe ' + sFileName);
    sFileName := ChangeFileExt(sFileName, '');
    lstBat.Add('java.exe ' + sFileName);
    lstBat.SaveToFile(sFilePath + '\' + 'Java.bat');

    ShellExecute(GetDesktopWindow, PChar('open'), PChar('cmd.exe '),
      PChar('/k ' + sFilePath + '\' + 'Java.bat'), PChar(''), SW_SHOWNORMAL);
  finally
    lstBat.Free;
  end;
end;


procedure RunDelphi(lstFile: TStringList; ASelectedFile: string);
var
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  sProjectFile, sFilePath, sDelphiCompiler: string;
begin

  sDelphiCompiler := GetDatabaseFilePath;
  if not SameText(sDelphiCompiler, '') then
  begin
    sFilePath := ExtractFileDir(ASelectedFile);
    FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
    StartupInfo.cb := SizeOf(TStartupInfo);

    StartupInfo.dwFlags := STARTF_USESHOWWINDOW + STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_HIDE;
  //    StartupInfo.wShowWindow := SW_Show;

    SetCurrentDir(sFilePath);
    if AnsiEndsText('\', sDelphiCompiler) then
    begin
      sDelphiCompiler := sDelphiCompiler + 'Bin\dcc32.exe';
    end
    else begin
      sDelphiCompiler := sDelphiCompiler + '\Bin\dcc32.exe';
    end;
      
    //创建新的进程
    CreateProcess(PChar(sDelphiCompiler), PChar(' -B ' + ASelectedFile), nil, nil, False,
        NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);

    if WaitForSingleObject(ProcessInfo.hProcess, INFINITE) = WAIT_OBJECT_0	then
    begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);

    end
    else begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);
    end;

    sProjectFile := ChangeFileExt(ASelectedFile, '.exe');
    ShellExecute(GetDesktopWindow, PChar('open'), PChar(sProjectFile),
        PChar(''), PChar(''), SW_SHOWNORMAL);
  end;
end;

procedure RunCSharp(lstFile: TStringList; ASelectedFile: string);
var
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  sProjectFile, sFilePath, sCompiler: string;
begin
//  sCompiler := 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe';
  sCompiler := GetCompiler('C#');
  if not SameText(sCompiler, '') then
  begin
    sFilePath := ExtractFileDir(ASelectedFile);
    FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
    StartupInfo.cb := SizeOf(TStartupInfo);

    StartupInfo.dwFlags := STARTF_USESHOWWINDOW + STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_HIDE;
  //    StartupInfo.wShowWindow := SW_Show;

    SetCurrentDir(sFilePath);
    //创建新的进程
    CreateProcess(PChar(sCompiler), PChar(' ' + ASelectedFile + Format(' /p:OutputPath=%s', [sFilePath])), nil, nil, False,
        NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);

    if WaitForSingleObject(ProcessInfo.hProcess, INFINITE) = WAIT_OBJECT_0	then
    begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);

    end
    else begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);
    end;

    sProjectFile := ChangeFileExt(ASelectedFile, '.exe');
    ShellExecute(GetDesktopWindow, PChar('open'), PChar(sProjectFile),
        PChar(''), PChar(''), SW_SHOWNORMAL);
  end;
end;

procedure RunVC6(lstFile: TStringList; ASelectedFile: string);
var
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  sProjectFile, sFilePath, sCompiler, sFileName: string;
begin
  sCompiler := GetCompiler('VC6');
  if not SameText(sCompiler, '') then
  begin
    sFilePath := ExtractFileDir(ASelectedFile);
    FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
    StartupInfo.cb := SizeOf(TStartupInfo);

    StartupInfo.dwFlags := STARTF_USESHOWWINDOW + STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_HIDE;
  //    StartupInfo.wShowWindow := SW_Show;

    SetCurrentDir(sFilePath);
    //创建新的进程
    CreateProcess(PChar(sCompiler), PChar(' ' + ASelectedFile + ' /make /rebuild '), nil, nil, False,
        NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);

    if WaitForSingleObject(ProcessInfo.hProcess, INFINITE) = WAIT_OBJECT_0	then
    begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);

    end
    else begin
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(ProcessInfo.hProcess);
    end;

    sFileName := ExtractFileName(ASelectedFile);
    if DirectoryExists(sFilePath + '\' + 'Debug') then
    begin
      sProjectFile := sFilePath + '\' + 'Debug\' +  ChangeFileExt(sFileName, '.exe');
      ShellExecute(GetDesktopWindow, PChar('open'), PChar(sProjectFile),
          PChar(''), PChar(''), SW_SHOWNORMAL);
    end
    else begin
      if DirectoryExists(sFilePath + '\' + 'Release') then
      begin
        sProjectFile := sFilePath + '\' + 'Release\' +  ChangeFileExt(sFileName, '.exe');
        ShellExecute(GetDesktopWindow, PChar('open'), PChar(sProjectFile),
            PChar(''), PChar(''), SW_SHOWNORMAL);
      end;
    end;
  end;
end;

procedure RunSignleFile(AFileName: String);
var
  sExt: string;
begin
  sExt := ExtractFileExt(AFileName);

  if SameText(sExt, '.java') then
  begin
    RunJava(AFileName);
  end;
end;

procedure RunAllFile(AllFile, SelectedFile: string);
var
  lstFile: TStringList;
  sExt: string;
begin
  lstFile := TStringList.Create;
  lstFile.CommaText := AllFile;

  sExt := ExtractFileExt(SelectedFile);

  if SameText(sExt, '.dpr') then
  begin
    RunDelphi(lstFile, SelectedFile);
  end;

  if SameText(sExt, '.csproj') then
  begin
    RunCSharp(lstFile, SelectedFile);
  end;

  if SameText(sExt, '.dsp') then
  begin
    RunVC6(lstFile, SelectedFile);
  end;  

  lstFile.Free;
end;

end.
