我正在嘗試制作一個應用程式來測驗我打算稍后添加到我的主程式中的某些功能,但沒有破壞我的主程式的風險。
我是 Pascal 的新手,但我仍然不明白有多少東西有效。
該程式的目標是,通過在同一應用程式中執行的 PowerShell 命令,獲取多個 JSON,每個 JSON 從特定目錄中遍歷并檢查某些內容。
這些事情可能是某些目錄中存在特定的檔案擴展名,或者其中存在大量資訊。
在 Delphi 中為此應用程式創建 3 個物件。一個啟動程式的按鈕、一個 Timer 和一個 JvCreateProcess。
定時器的時間間隔屬性是 10 (ms)。onTimer屬性就是Timer1Timer方法。
Timer1Timer代碼:
procedure TUProbando.Timer1Timer(Sender: TObject);
var
Comando: TStrings;
ValorJSON: TStrings;
begin
if ContadorDirectorios = Length(rutas) then
begin
Timer1.Enabled := false;
exit;
end;
Timer1.Enabled := false;
Lista.Clear;
// spacer to improve visibilitys
memo_Salida_Command_gci.Lines.Add('******* ' rutas[ContadorDirectorios]
' *******');
Comando := TStringList.Create;
try
// Open Powershell
Comando.Add('C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe "');
// I add the command line to create a JSON with the contents of the specified directory
Comando.Add('"gci ' rutas[ContadorDirectorios]
' -Recurse | ConvertTo-Json"');
// I add the command line to the process
JvCreateProcess1.CommandLine := Comando.Text;
// I run the process
JvCreateProcess1.run;
ValorJSON := JvCreateProcess1.ConsoleOutput;
finally
begin
Comando.Free;
end;
end;
end;
該rutas[]陣列是一個字串陣列,其中包含要檢查的目錄。
rutas: array [0 .. 2] of String = ('C:\Users\operario43\Desktop',
'C:\Users\operario43\Documents', 'C:\Users\operario43\Pictures');
現在,JvCreateProcess1代碼:
procedure TUProbando.JvCreateProcess1Terminate(Sender: TObject;
ExitCode: Cardinal);
begin
// Calculate the size of the current directory
// I WANT GET JSON OF PREVIOUS POWER SHELL COMMAND HERE
SizeDirectory := GetSizeFromJson('JSON HERE', Extensiones);
if checkSizeDirectory(SizeDirectory, SizeControlDirectory) then
begin
ShowMessage('This Directory' rutas[ContadorDirectorios]
' has important files not protected by a backup');
end;
// 1 counter of directories traversed
inc(ContadorDirectorios);
end;
我使用的其他方法:
function GetSizeFromJson(JSON: String; vExtensiones: array of string): integer;
var
Contenedor: TJSONArray;
Jfichero: TJSONObject;
JNombre: TJSONValue;
// value of the 'length' element of each element of the JSON
JSizeFile: TJSONNumber; //
I: integer;
SizeDirectory: Int64;
begin
SizeDirectory := 0;
result := -1;
try
Contenedor := TJSONObject.ParseJSONValue(JSON) as TJSONArray;
if Contenedor = nil then
begin
ShowMessage('Error al parsear el json' JSON);
exit;
end;
for I := 0 to Contenedor.Count - 1 do
begin
Jfichero := Contenedor.Items[I] as TJSONObject;
if Jfichero <> nil then
begin
// I extract the name of the element
JNombre := Jfichero.GetValue('Name');
// If the extensions of the files in the directory are in the 'Extensions' array
if MatchStr(ExtractFileExt(JNombre.Value), vExtensiones) then
begin
// get the value of the lenght element in bytes
JSizeFile := Jfichero.GetValue('Length') as TJSONNumber;
if JSizeFile <> nil then
begin
// I add the value of 'leght' of the element to the variable SizeDirectory
inc(SizeDirectory, JSizeFile.AsInt);
end; // if JSizeFile <> nil
end; // if MatchStr(ExtractFileExt(JNombre.Value), vExtensiones)
end; // if Jfichero <> nil
end; // for I := 0 to Contenedor.Count - 1
// I return the value of the size of the directory
result := SizeDirectory;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
// method to find out if the size of the current directory exceeds the recommended size for directories in the variable called SizeControlDirectory
function checkSizeDirectory(vSizeDirectory, vSizeControlDirectory
: Int64): Boolean;
var
Contenedor: TJSONArray;
begin
result := false;
vSizeDirectory := GetSizeFromJson(Contenedor.ToString, Extensiones);
if vSizeDirectory > vSizeControlDirectory then
begin
ShowMessage('Directory ' rutas[ContadorDirectorios]
' have files don't protected by Backup');
end;
end;
我的問題是,如何為 JvCreateProcess1Terminate 方法獲取 JSON?
我進行了很多更改以使其正常作業,并制作了一小段代碼以使其更易于管理。
uj5u.com熱心網友回復:
只是一個注釋可能對某人有幫助。
您可以將任何 Windows 終端命令或應用程式的輸出保存到檔案中。只需在 ExeName 或命令后添加“> FileName”,然后輸出將保存到“FileName”。我也可以從 Delphi 使用它。假設我希望將名為 MyApp.exe 的程式的輸出保存到檔案中,那么我可以使用以下命令:
Myprog := 'd:\MyApp.exe > FullOutputFileName';
r := ShellExecute(0, 'open', PChar(Myprog), nil, nil, SW_HIDE);
if r <> o then
//Check for error
else
//load the file FullOutputFileName and get results
當使用一些終端內部命令,如“dir、ver、vol、...”時,我創建了一個批處理檔案 (FileName.bat),其中包含我想要執行的一個或多個命令,然后我使用 shellexecute 來執行這個檔案。
筆記:
- 您還可以使用“>> FileName”將輸出附加到檔案末尾。
- 此方法速度較慢,因此不建議在回圈中使用它。
- mORMot具有良好且易于使用的 JSON 實作。
uj5u.com熱心網友回復:
我可以理解你有兩個部分要做。
- 執行 windows 終端命令并將輸出放入字串。
- 將您獲得的字串轉換為 JSON。
對于我在使用檔案捕獲輸出(舊方式)之前提到的第一部分,這里有一個使用 pips 執行相同操作的函式。
function ExecAndCapture(const ACmdLine: string; var AOutput: string): Boolean;
const
cBufferSize = 2048;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
begin
Result := False;
AOutput := '';
with SA do begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE);
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := GetCurrentDir;
Handle := CreateProcess(nil, PChar(ACmdLine),
nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
AOutput := AOutput string(Buffer);
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
Result := True;
finally
CloseHandle(StdOutPipeRead);
end;
end;
對于第二部分,我更喜歡使用 mOrmot 框架作為以下示例:
procedure DoTest();
var
s : string;
UtfStr : RawUTF8;
i : Integer;
O : Variant;
begin
if ExecAndCapture('powershell.exe gci E:\AIIconPack -Recurse | ConvertTo-Json', S) then
begin
UtfStr := s;
O := TDocVariant.NewJSON(UtfStr);
for i := 0 to O._Count-1 do
begin
Writeln(i 1, ':', O._(i).Name, ' <> ', O._(i).Parent.Name);
end;
end;
end;
如果您使用 mORMot,那么您的 (GetSizeFromJson) 將是這樣的(我沒有測驗它):
function GetSizeFromJson(JSON: String; vExtensiones: array of string): integer;
var
Contenedor: Variant;
Jfichero: Variant;
JNombre: string;
// value of the 'length' element of each element of the JSON
JSizeFile: Integer; //
I: integer;
SizeDirectory: Int64;
begin
SizeDirectory := 0;
result := -1;
try
Contenedor := TDocVariant.NewJSON(JSON);
if Contenedor = UnAssigned then
begin
ShowMessage('Error al parsear el json' JSON);
exit;
end;
for I := 0 to Contenedor._Count - 1 do
begin
Jfichero := O._(i);
if Jfichero <> UnAssigned then
begin
// I extract the name of the element
JNombre := Jfichero.Name;
// If the extensions of the files in the directory are in the 'Extensions' array
if MatchStr(ExtractFileExt(JNombre), vExtensiones) then
begin
// get the value of the lenght element in bytes
JSizeFile := Jfichero.Length;
if JSizeFile <> nil then
begin
// I add the value of 'leght' of the element to the variable SizeDirectory
inc(SizeDirectory, JSizeFile);
end; // if JSizeFile <> nil
end; // if MatchStr(ExtractFileExt(JNombre.Value), vExtensiones)
end; // if Jfichero <> nil
end; // for I := 0 to Contenedor.Count - 1
// I return the value of the size of the directory
result := SizeDirectory;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
我希望這會對某人有所幫助。
uj5u.com熱心網友回復:
這里有一小段代碼片段,您可以使用它來執行帶有 JVCreateProcess 組件的 DOS 應用程式:
procedure TForm2.JvImgBtn6Click(Sender: TObject);
var
path : String;
begin
try
path := ExtractFilePath(Application.ExeName);
with JvCreateProcess1 do
begin
ApplicationName := 'C:\windows\system32\cmd.exe';
CurrentDirectory := path;
CommandLine := '/c '
path 'build.bat ' path;
ShowMessage(ApplicationName #13#10 CommandLine);
Run;
end;
finally
end;
end;
在此代碼中,我使用 cmd.exe 引數 /C - 在“build.bat”執行完成后關閉 DOS 終端行程視窗。
如果您想保持打開 DOS 終端視窗,請使用 /k 引數。
'build.bat' 之前和之后的路徑變數代表:C :
\path\to\build.bat C:\path\as\parameter
所以,build.bat 可以有演示的內容:
@echo off
set DEVPATH=%1
dir
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/526135.html
標籤:电源外壳德尔福过程帕斯卡
上一篇:在腳本中實作多執行緒/并行處理
