unit1.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, EditBtn,
  6. ComCtrls, Buttons, ExtCtrls, Process, Math;
  7. type
  8. { TForm1 }
  9. TForm1 = class(TForm)
  10. btnStart: TBitBtn;
  11. btnStop: TBitBtn;
  12. chkKVM: TCheckBox;
  13. edtCustom: TEdit;
  14. edtImageFile: TFileNameEdit;
  15. edtHarddiskFile: TFileNameEdit;
  16. GroupBox1: TGroupBox;
  17. GroupBox2: TGroupBox;
  18. Image1: TImage;
  19. Label1: TLabel;
  20. Label2: TLabel;
  21. Label3: TLabel;
  22. Label4: TLabel;
  23. lblCores: TLabel;
  24. lblRAM: TLabel;
  25. trkCores: TTrackBar;
  26. trkRAM: TTrackBar;
  27. procedure btnStartClick(Sender: TObject);
  28. procedure btnStopClick(Sender: TObject);
  29. procedure FormCreate(Sender: TObject);
  30. procedure FormDestroy(Sender: TObject);
  31. procedure trkCoresChange(Sender: TObject);
  32. procedure trkRAMChange(Sender: TObject);
  33. private
  34. function ConvertBytes(Bytes: Int64): string;
  35. function GetCommandOutput(command: string): string;
  36. public
  37. end;
  38. var
  39. Form1: TForm1;
  40. //
  41. AProcess: TProcess;
  42. implementation
  43. {$R *.lfm}
  44. { TForm1 }
  45. procedure TForm1.btnStartClick(Sender: TObject);
  46. var
  47. SystemArchitecture: string;
  48. Params: TStringArray;
  49. Param, s: string;
  50. begin
  51. // If already running then don't start vm
  52. if (AProcess <> nil) and (AProcess.Running = true) then Exit;
  53. if AProcess = nil then
  54. AProcess := TProcess.Create(nil);
  55. // TODO: Add specific qemu executable
  56. SystemArchitecture:=GetCommandOutput('uname -m');
  57. // It becomes something like: qemu-system-x86_64
  58. AProcess.Executable:= 'qemu-system-'+SystemArchitecture;
  59. AProcess.Parameters.Clear;
  60. // ISO image
  61. AProcess.Parameters.Add('--cdrom');
  62. AProcess.Parameters.Add(edtImageFile.FileName);
  63. // Hard Disk image
  64. if FileExists(edtHarddiskFile.FileName) then begin
  65. AProcess.Parameters.Add('--hda');
  66. AProcess.Parameters.Add(edtHarddiskFile.FileName);
  67. end;
  68. // CPU Cores
  69. AProcess.Parameters.Add('-smp');
  70. AProcess.Parameters.Add(inttostr(trkCores.Position));
  71. // Memory
  72. AProcess.Parameters.Add('-m');
  73. AProcess.Parameters.Add(inttostr(trkRAM.Position));
  74. // KVM
  75. if chkKVM.Checked then
  76. AProcess.Parameters.Add('-enable-kvm');
  77. // Custom parameters
  78. Params := string(edtCustom.Text).Split(' ');
  79. for Param in Params do
  80. AProcess.Parameters.Add(Param);
  81. AProcess.Options := AProcess.Options + [poUsePipes];
  82. AProcess.Execute;
  83. end;
  84. procedure TForm1.btnStopClick(Sender: TObject);
  85. begin
  86. AProcess.Terminate(0);
  87. end;
  88. procedure TForm1.FormCreate(Sender: TObject);
  89. var
  90. TotalMemory: longint;
  91. begin
  92. // RAM
  93. TotalMemory := StrToInt( GetCommandOutput('cat /proc/meminfo | head -n 1 | awk "{print \$2}"') ) div 1024;
  94. trkRAM.Max:=TotalMemory;
  95. trkRAM.Position:=TotalMemory div 4;
  96. // CPU Cores
  97. trkCores.Max:=StrToInt( GetCommandOutput('grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo "$NUMBER_OF_PROCESSOR"') );
  98. trkCores.Position:=trkCores.Max;
  99. end;
  100. procedure TForm1.FormDestroy(Sender: TObject);
  101. begin
  102. AProcess.Free;
  103. end;
  104. procedure TForm1.trkCoresChange(Sender: TObject);
  105. begin
  106. lblCores.Caption:=inttostr( trkCores.Position );
  107. end;
  108. procedure TForm1.trkRAMChange(Sender: TObject);
  109. begin
  110. lblRAM.Caption:= ConvertBytes(trkRAM.Position*1024*1024);
  111. end;
  112. // Source: https://stackoverflow.com/a/30549584
  113. function TForm1.ConvertBytes(Bytes: Int64): string;
  114. const
  115. Description: Array [0 .. 8] of string = ('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
  116. var
  117. i: Integer;
  118. begin
  119. i := 0;
  120. while Bytes > Power(1024, i + 1) do
  121. Inc(i);
  122. Result := FormatFloat('###0.##', Bytes / IntPower(1024, i)) + ' ' + Description[i];
  123. end;
  124. function TForm1.GetCommandOutput(Command:string):string;
  125. var
  126. s: ansistring;
  127. begin
  128. if RunCommand('/bin/sh', ['-c', Command], s) then
  129. Result := Trim(s);
  130. // We use Trim() to cut off access carriage return at the end
  131. end;
  132. end.