powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Curl, командная строка и анализ ответа
1 сообщений из 1, страница 1 из 1
Curl, командная строка и анализ ответа
    #39573717
A-MaR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеется следующий код, выполняющий отправку алкоголя в ЕГАИС при помощи Curl:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
const 
  cSendToUTM = '%s -F "xml_file=@%s" %s/xml';
var
  CurlPath, XMLPath, UTM_URL: string //Пути соответственно к Curl.exe и отправляемому XML-файлу, и URL, куда отправляем

function SendToUTM: boolean;
const
  XmlSign = '<?xml';
var BatStr, SendResult: string;
    XMLPos: integer;		
begin
  //Отправка чека в УТМ при помощи Curl
  BatStr := Format(cSendToUTM, [CurlPath, XMLPath, UTM_URL]);
  SendResult := CreateAndRunBatFile(ExtractFilePath(Application.ExeName) + 'SendToUTM.bat', BatStr, True);
  XmlPos := Pos(XmlSign, SendResult);
  if XmlPos > 0 then begin
    {В ответе содержится XML-файл, все ОК, обработка и печать
     ...
    }
    Result := true;
  end
  else begin
    {Обработка ошибок
     ...
    }
    Result := false;
  end;
end;

function CreateAndRunBatFile(FilePath, BatStr: string; FromUTF: Boolean = False): string;
var SList: TStringList;
    ResultStrDos: PChar;
begin
  SList := TStringList.Create;
  SList.Text := BatStr;
  if FileExists(FilePath) then
    DeleteFile(FilePath);
  SList.SaveToFile(FilePath);
  ResultStrDos := PChar(GetDosOutput(FilePath));

  //Здесь спорный момент:
  if FromUTF then begin
    Result := UTF8Decode(ResultStrDos);
  end
  else begin
    OemToAnsi(ResultStrDos, ResultStrDos);
    Result := ResultStrDos;
  end;

  SList.Free;
  DeleteFile(PChar(FilePath));          
end;

function GetDosOutput(const CommandLine: string): string;
{Данная функция позаимствована где-то на просторах Интернета и включена практически без изменений}
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of Char;
  BytesRead: Cardinal;
  WorkDir, Line: string;
begin
  with SA do
  begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  // создаем пайп для перенаправления стандартного вывода
  CreatePipe(StdOutPipeRead, // дескриптор чтения
    StdOutPipeWrite, // дескриптор записи
    @SA, // аттрибуты безопасности
    0 // количество байт принятых для пайпа - 0 по умолчанию
    );
  try
    // Создаем дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
    // а так же проверяем, чтобы он не показывался на экране.
    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 := ExtractFilePath(CommandLine);
    WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);

    // Теперь, когда дескриптор получен, для безопасности закрываем запись.
    // Нам не нужно, чтобы произошло случайное чтение или запись.
    CloseHandle(StdOutPipeWrite);
    // если процесс может быть создан, то дескриптор, это его вывод
    if not WasOK then
      raise Exception.Create('Ошибка создания процесса')
    else
    try
        // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
      Line := '';
      repeat
        WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

          // есть ли что-нибудь еще для чтения?
        if BytesRead > 0 then
        begin
            // завершаем буфер PChar-ом
          Buffer[BytesRead] := #0;
            // добавляем буфер в общий вывод
          Line := Line + Buffer;
        end;
      until not WasOK or (BytesRead = 0);
        // ждем, пока завершится консольное приложение
      WaitForSingleObject(PI.hProcess, INFINITE);
    finally
        // Закрываем все оставшиеся дескрипторы
      CloseHandle(PI.hThread);
      CloseHandle(PI.hProcess);
    end;
  finally
    result := Line;
    CloseHandle(StdOutPipeRead);
  end;
end;  



Работает с июля прошлого года, проблем почти не доставлял. Но сейчас, в связи с последними изменениями по УТМ, в сообщения об ошибках могут включаться ключевые фразы, содержащие русские символы, которые нужно анализировать. При том что сам ответ УТМ отправляет в формате UTF. Именно по этой причине в функции CreateAndRunBatFile появился параметр FromUTF. Одна такая ситуация с русскими символами уже имела место (у клиента на боевом УТМ), но тогда параметра FromUTF еще не было, и расшифровать ответ так и не смогли. В конце концов пришли к выводу, что портит все преобразование OemToAnsi, но это только предположение.

Собственно вопрос по функции CreateAndRunBatFile: достаточно ли будет в случае UTF преобразования UTF8Decode, или же все-таки его необходимо применять до/после OemToAnsi ? Смоделировать ситуацию искусственно не представляется возможным по причине отсутствия тестового УТМ, есть только боевой у клиентов, поэтому экспериментировать придется "по живому".
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Curl, командная строка и анализ ответа
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]