0

I'm writing a small integration testing framework to a suite of application written in Delphi 10.2 (win32 target).

My idea was to detect a specific command-lien parameter and, if it is present, run the test, printing the result to STDOUT and the console and then exiting with either 0 (no error) or 1 (error) so that the build script can pickup the result.

That worked well except for the last part: I'm unable to set the process exit code properly and read it back from the calling script. I'm always getting the value -1073741515 back instead.

Since the program is, in theory, a GUI application, I wrote some code that would allow it to attach to the calling console (or create one if not present) and maybe my problem comes from that.

Here is my code:

  UIAbstraction.writeln('Integration testing of '+ModuleName, dmEmphasis);
  if Errors.Count > 0 then
  begin
    UIAbstraction.writeln('Erros occured during integration tests:');
    Errors.ForEach(procedure (const Aline: string)
      begin
        UIAbstraction.writeln(ALine, dmError);
      end
    );
    UIAbstraction.Detach;
    ExitProcess(cardinal(1));
  end
  else
  begin
    UIAbstraction.writeln('Integration tests sucessfull', dmSuccess);
    UIAbstraction.Detach;
    ExitProcess(cardinal(0));
  end;

UIAbstraction is a small class that, well, abstract the UI (the goal is to be easily able to inject a different implementation later that could integrate with a different integration test system). It mostly has 2 meaningful methods: Attach and detach:

procedure TConsoleConnector.Attach;
begin
  IsAttached:=AttachConsole(-1);
  if not IsAttached then
    IsAttached := GetlastError = 5; // 5 = ACCESS_DENIED = already attached
  if not IsAttached
  then
  begin
    IsAttached:=AllocConsole;
    if not IsAttached then
      RaiseLastOSError;
  end;
end;


procedure TConsoleConnector.Detach;
begin
  if IsAttached then
    FreeConsole;
  IsAttached:=false;
end;

Unfortunately, when I run this code from the command line and follows it with echo %errorlevel% I always get -1073741515 instead of the expected 0 or 1.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Stephane
  • 3,173
  • 3
  • 29
  • 42
  • 1
    [System.ExitCode](http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.ExitCode) – J... Oct 03 '17 at 14:51
  • You shouldn't use `ExitProcess`, normally. This kills your application un-gracefully. – J... Oct 03 '17 at 14:53
  • @J... Thank you, but it isn't the case here: the application captures the console until it terminates so I'm certain that it has terminated before the %ERRORLEVEL% line is interpreted. – Stephane Oct 03 '17 at 15:22
  • @J... I understand the consequences of ExitProcess. I have taken them into account when designing the testing framework. But thank you for raising that point anyway – Stephane Oct 03 '17 at 15:23
  • Are you running the GUI application from the command line via `start /wait`? Otherwise CMD doesn't wait to capture the exit code. It only waits automatically at the interactive prompt for console applications that inherit the current console, because if it didn't wait then both programs would compete for the console. – Eryk Sun Oct 03 '17 at 15:30
  • FYI, -1073741515 is most likely `STATUS_DLL_NOT_FOUND` (0xC0000135). It's easier to look up information about an `NTSTATUS` or `HRESULT` code when you search for it as a non-negative, hexadecimal number. – Eryk Sun Oct 03 '17 at 15:31
  • Have you tried running it in a batch file rather than the command prompt (as suggested - kind of - in the link @J... gave)? – Dsm Oct 03 '17 at 15:31
  • @Dsm I just did and... It worked. Somehow, it seems that running the manually application from a console will not let it modify the %ERRORLEVEL% env variable but doing so in a batch file works fine. I'll be damned if I understand why but, at least, my problem seems to be solved. – Stephane Oct 03 '17 at 15:36
  • Thank you all for your help. If one (or both) care to write an answer, I'll be happy to accept it (se the last edit for the details). – Stephane Oct 03 '17 at 15:38
  • @Stephane ...or just accept the dupe – J... Oct 03 '17 at 15:42
  • As mentioned in the link @J... gave, when you are running in the console, the console does not wait for the exe to return, so the echo is being executed before the exe has returned its value. – Dsm Oct 03 '17 at 15:42
  • CMD does not wait on and call `GetExitCodeProcess` for a GUI process that's run from the command line unless you use `start /wait`. It has absolutely no idea that you've attached to the console. In principle it could do that by keeping the process handle open to verify the process ID and periodically calling `GetConsoleProcessList` to check if a GUI child has attached back to the console, but it doesn't do that and there's really not much need for it. – Eryk Sun Oct 03 '17 at 15:44

0 Answers0