delphidosdicomdcmtk

How to get the Study Instance UID (0020,000d) from DOS and display it in a memo with Delphi/Delphi 5 correctly? (DICOM)


i'm currently trying to implement a procedure called "GetDosOutput" in Delphi 5/ Delphi 10. In this procedure I want to get the DOS output from a worklist query (via DCMTK toolbox) and display it in a memo. The problem is that just the study instance UID isnt transfered/displayed correctly in the memo. It gets cut of right behind the end and several lines after it get also cut.

I have the following code and the following results from DOS, where everything is displayed correctly, and the memo:

// get output from cmd.exe and display on memo
procedure TForm4.OnReadPipeOutput(Sender: THandle);
var
  BytesRead: DWORD;
  BufferPtr: PAnsiChar; // Pointer to a dynamic array
  BufferSize: Integer; // Size of the dynamic array
  TempStr: AnsiString; // Temporary variable to hold the converted string
  WasOK: Boolean;
begin
  BufferSize := 1024; // Initial size of the dynamic array
  GetMem(BufferPtr, BufferSize); // Allocate memory for the dynamic array
  try
    repeat
      WasOK := ReadFile(THandle(Sender), BufferPtr^, BufferSize, BytesRead, nil);
      if BytesRead > 0 then
      begin
        SetString(TempStr, PAnsiChar(BufferPtr), BytesRead); // Convert the buffer to a string
        //ShowMessage(BufferPtr);
        Memo1.Lines.Add(TempStr); // Append the output to the memo
      end;
    until not WasOK or (BytesRead = 0);
  finally
    FreeMem(BufferPtr); // Free the memory used by the dynamic array
  end;
end;

// send command to cmd.exe, get output from cmd.exe and display on memo
procedure TForm4.GetDosOutput(Command:String);
var
  Security: TSecurityAttributes;
  ReadPipe, WritePipe: THandle;
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  Handle: Boolean;
begin
  memo1.Clear;
  if command = '' then begin
    Exit;
  end;
  Security.nLength := SizeOf(TSecurityAttributes);
  Security.bInheritHandle := True;
  Security.lpSecurityDescriptor := nil;
  if not CreatePipe(ReadPipe, WritePipe, @Security, 0) then begin
    Exit;
  end;
  try
    FillChar(StartupInfo, SizeOf(StartupInfo), 0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo.wShowWindow := SW_HIDE;
    StartupInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
    StartupInfo.hStdOutput := WritePipe;
    StartupInfo.hStdError := WritePipe;

    Handle := CreateProcess(nil, PChar('cmd.exe /c ' + Command), nil, nil, True, CREATE_NEW_CONSOLE, nil, nil, StartupInfo, ProcessInfo);
    CloseHandle(WritePipe);
    if Handle then begin
      try
        // get output from cmd.exe and display on memo
        OnReadPipeOutput(ReadPipe);
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      finally
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      end;
    end;

  finally
    CloseHandle(ReadPipe);
  end;
end;

// query a worklist from HIS
procedure TForm4.WorklistQuery();
var
  Command:String;
  AET,IP,Port,WlQPath: String;
begin
  edtCmd.Text := '';

  AET := Trim(edtAET.Text)+' ';
  IP := Trim(edtIP.Text)+' ';
  Port := Trim(edtPort.Text)+' ';

  WlQPath := '"'+ Trim(edtWlQFilepath.Text) +'"';   //Worklist path

  Command := 'cd /d ' + dcmtkPath +'&&findscu -v --call ' + AET +  IP +  Port +  WlQPath;

  edtCmd.Text := Command;
  GetDosOutput(Command);
end;

Memo: enter image description here

The result should be like the DOS Output:(https://i.sstatic.net/lJMCx.png)

I tried a lot e.g. to reproduce the error with the other attributes like patient ID but just the study instance UID with the RV "UI" gives problems.

I appreciate some help (:

Edit: I tried "Memo.SelStart ... etc" from the comment section with following result: 2

Kind regards


Solution

  • I tried a lot e.g. to reproduce the error with the other attributes like patient ID but just the study instance UID with the RV "UI" gives problems.

    In DICOM, odd-length data element values have to be padded to an even length. For UI (Unique Identifier) values, the padding character is a zero byte (0x00). Since the UI value in your sample (see referenced screenshot) has an odd length, your parsing code might have a problem with the trailing zero byte.

    One solution would be to remove the padding before parsing. The easiest way to do this is to add the option +dc (short version of --enable-correction) to your findscu call. By default, option -dc (--disable-correction) is used. See documentation of this tool.