Lazarus

Programming => Operating Systems => Linux => Topic started by: maurobio on July 28, 2021, 11:48:28 pm

Title: [SOLVED] Problem running external program under Linux
Post by: maurobio on July 28, 2021, 11:48:28 pm
Dear ALL,

I am struck with a strange problem when attempting to run an external program from a Lazarus GUI application under Linux.

I cannot distribute my real application at this time, but it is a relatively straightforward program which executes a C program, passing the name of text file as its only argument and counts the lines in the file; the program then enters a command loop where the user must type 'quit' in order to exit the program. Under Windows, the application works fine, but it fails under Linux. without issuing any error messages.

I am running Lazarus 1.8.2 under Lubuntu 18.04.5 LTS. I have installed Lazarus from the Ubuntu repositories, and therefore that is not the most recent version.

The only reasonable explanation I can find for this problem is that it may be related to that old version of Lazarus. However, before updating, I would like to be sure that it is really the problem. Could someone give it a try under a more recent version of Lazarus for Linux?

My sample code is attached. I hope that perusal of the code will make the problem easier to understand.

Thanks in advance!

With best wishes,
Title: Re: Problem running external program under Linux
Post by: rsz on July 29, 2021, 03:52:44 am
Hi,

I don't have a windows machine to compare to right now but I believe the issue you are experiencing is due to how Linux handles console applications differently than Windows. I assume you expect a command prompt to be opened on Linux when the counter program is run?

On Linux you must execute a terminal emulator explicitly (such as xterm) and then pass it arguments to execute your counter program rather than launching the counter program directly.
Title: Re: Problem running external program under Linux
Post by: Jurassic Pork on July 29, 2021, 06:52:12 am
hello,
have you tried to launch your compiled program in a xterm ? if you launch your program in the IDE , display the console In/out window ->  View/Debug Windows/Console In/Output  may be View/Debug Windows/Console Terminal in your Lazarus version.
Friendly, J.P
Title: Re: Problem running external program under Linux
Post by: lucamar on July 29, 2021, 07:26:39 am
The C program seems to always return exit code 0; in *nix you should instead (or also) check ExitStatus, which will tell you if there was some problem running the program irrespective of what the program itself returns as ExitCode.
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 01:12:59 pm
Dear ALL,

Thank you very much indeed for your replies. However, I am still at a loss. I could not fully understand the issue with 'xterm'. But as far as I can see, a console program cannot be executed from a GUI application under Linux in the same way it can be under Windows.

How do I 'execute a terminal emulator explicitly', as suggested by @rsz? Could an example be provided? Also, I would appreciate a tip on how to check ExitStatus as suggested by @lucamar. Unfortunately, none of the explanations provided in the links below mention GUI applications:

https://wiki.freepascal.org/Executing_External_Programs#Using_fdisk_with_sudo_on_Linux (https://wiki.freepascal.org/Executing_External_Programs#Using_fdisk_with_sudo_on_Linux)
https://forum.lazarus.freepascal.org/index.php?topic=10462.0 (https://forum.lazarus.freepascal.org/index.php?topic=10462.0)

I attach a slightly updated version of my sample code, now including a 'runcounter.pas' program as a console-mode application, which works fine under both Linux and Windows.

Thanks again for your time and patience!

With best wishes,
Title: Re: Problem running external program under Linux
Post by: lucamar on July 29, 2021, 02:44:49 pm
But as far as I can see, a console program cannot be executed from a GUI application under Linux in the same way it can be under Windows.

It can, only Linux doesn't need a "command prompt" or a console window to execute it, which is why if you want that you have to run the program under a terminal emulator. That is, you "run" the terminal and pass to it, as parameters, the program you want it to execute.

Quote
How do I 'execute a terminal emulator explicitly', as suggested by @rsz? Could an example be provided?

Basically, like this (just Q&D example, mind!):
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Process;;
  7.  
  8. var
  9.   AProcess: TProcess;
  10.  
  11. begin
  12.   AProcess := TProcess.Create(Nil);
  13.   try
  14.     AProcess.Executable := DetectXTerm;
  15.     AProcess.Parameters.Add('counter');
  16.     AProcess.Parameters.Add('lines.txt');
  17.     AProcess.Options := AProcess.Options + [poWaitOnExit];
  18.     AProcess.Execute;
  19.   finally
  20.     AProcess.Free;
  21.   end;
  22. end.

Quote
Also, I would appreciate a tip on how to check ExitStatus as suggested by @lucamar.

Well, you have to know the possible codes to diagnose the problem but at a basic level you check against zero, as you do with ExitCode, and "barf" out if it failed.
Title: Re: Problem running external program under Linux
Post by: sstvmaster on July 29, 2021, 02:53:34 pm
... but it is a relatively straightforward program which executes a C program, passing the name of text file as its only argument and counts the lines in the file ...

Why don't you count the lines from this file youself?
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 03:31:16 pm
@lucamar,

Unfortunately, it still didn't work. DetectXTerm returns 'x-terminal-emulator', which bash claims does not exist on my system (shouldn't it return LXTerminal, since I am running Lubuntu?). My program just stalls as before.

@sstvmaster.

To count lines in a file is not really my problem; the 'counter' program is just a dummy sample program which emulates the behaviour of the 'true' program I am attempting to run from my GUI (that is, a console program which reads a file passed as argument and waits for user commands until a 'quit' command is typed).

Again, thank you!

With best wishes,
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 03:46:23 pm
It can, only Linux doesn't need a "command prompt" or a console window to execute it, which is why if you want that you have to run the program under a terminal emulator. That is, you "run" the terminal and pass to it, as parameters, the program you want it to execute.

It will probably never need a window (i.e. xterm or equivalent) to run a child program, unless that program requires that the DISPLAY or one of the XDG_ shell variables etc. to be set up sensibly. I know that sounds silly for a command line program, but consider the case of the Subversion client or Sudo which can tell the desktop environment to display a prettified password prompt dialog(ue).

It might need a shell if, for some reason, the command being passed includes redirection/piping or variable substitution etc., there's usually ways of working round this.

If termination is failing, it is likely to be because the parent is not waiting for activity to stop, or because the child is expecting something like \r\n and is only seeing \r.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: avra on July 29, 2021, 03:56:26 pm
Maybe it could help to take a look at https://bitbucket.org/avra/ct4laz. That is a GUI application which executes 7zip command line executable with parameters and processes it's output, while working on both Windows and Linux.
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 04:32:17 pm
@Avra,

Thanks a lot. But ct4laz seems to be a large collection of components, and I cannot install it at this time. Could you please point out a specific example out that collection, which I could take a look at?

With best wishes,
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 04:51:58 pm
This is something I've used in the past. I'm not saying it's good code and the actual child program name etc. is set up in a separate form, but I /am/ saying it works with a fair number of child programs (typically, an APL interpreter that requires something like )bye\r to terminate).

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.MenuConnectionConnectProgramClick(Sender: TObject);
  2.  
  3. var     process: TProcess= nil;
  4.         i: integer;
  5.  
  6.  
  7.   procedure shutdown(const msg: string= '');
  8.  
  9.   begin
  10.     if msg <> '' then begin
  11.       ConnectProgressForm.Label1.Caption := msg;
  12.       if StatusBar1.SimplePanel = true then     (* Won't mess up status bar     *)
  13.         FullWidth(msg)
  14.     end;
  15.     if process <> nil then
  16.       try
  17.         process.Terminate(0)
  18.       except
  19.       end;
  20.     FreeAndNil(process)
  21.   end { shutdown } ;
  22.  
  23.  
  24.   procedure unableToConnect(const server: string);
  25.  
  26.   begin
  27.   {$ifdef SMARTPOS }
  28.     MessageDlgPos('Unable to connect ' + server, mtError, [mbOK], 0,
  29.           (Left + Width div 2 + Screen.Width div 2) div 2,
  30.           (Top + Height div 2 + Screen.Height div 2) div 2)
  31.   {$else           }
  32.     MessageDlg('Unable to connect ' + server, mtError, [mbOK], 0)
  33.   {$endif SMARTPOS }
  34.   end { unableToConnect } ;
  35.  
  36.  
  37.   (* If the second parameter is false trim and return the first parameter.
  38.     Otherwise locate substrings that look like shell environment names and
  39.     expand them.
  40.   *)
  41.   function expand(const str: string; doExpand: boolean): string;
  42.  
  43.   var   unprocessed, name: string;
  44.  
  45.   begin
  46.     result := Trim(str);
  47.     if doExpand then begin
  48.       unprocessed := result;
  49.       result := '';
  50.       while unprocessed <> '' do begin
  51.         case unprocessed[1] of
  52.           '~': begin
  53.                  if result = '' then            (* At start only                *)
  54.                    result := UserHomeDirectory
  55.                  else
  56.                    result += '~';
  57.                  Delete(unprocessed, 1, 1)
  58.                end;
  59.           '\': begin
  60.                  Delete(unprocessed, 1, 1);     (* Backslash                    *)
  61.                  if unprocessed <> '' then begin
  62.                    result += unprocessed[1];    (* Might be special, don't care *)
  63.                    Delete(unprocessed, 1, 1)
  64.                  end
  65.                end;
  66.           '$': begin                    (* No provision here for \{ or \}       *)
  67.                  Delete(unprocessed, 1, 1);     (* Dollar                       *)
  68.                  name := '';
  69.                  if unprocessed <> '' then begin
  70.                    if unprocessed[1] <> '{' then
  71.                      while (unprocessed <> '') and
  72.                         (unprocessed[1] in ['0'..'9', 'A'..'Z', 'a'..'z', '_']) do begin
  73.                        name += unprocessed[1];
  74.                        Delete(unprocessed, 1, 1)
  75.                      end
  76.                    else begin
  77.                      Delete(unprocessed, 1, 1); (* Left brace                   *)
  78.                      while (unprocessed <> '') and (unprocessed[1] <> '}') do begin
  79.                        name += unprocessed[1];
  80.                        Delete(unprocessed, 1, 1)
  81.                      end;
  82.                      Delete(unprocessed, 1, 1)  (* Right brace                  *)
  83.                    end;
  84.                    if name <> '' then
  85.                      result += GetEnvironmentVariable(name)
  86.                  end
  87.                end
  88.         otherwise
  89.           result += unprocessed[1];
  90.           Delete(unprocessed, 1, 1)
  91.         end
  92.       end
  93.     end
  94.   end { expand } ;
  95.  
  96.  
  97. begin
  98.   if CurrentConnectionType() <> ConnectionNone then begin
  99.     unableToConnect('since already online');
  100.     exit
  101.   end;
  102.   process := TProcess.Create(nil);
  103.  
  104. (* If we're not here via a reconnect then display a form for extra program      *)
  105. (* parameters. Even if we know there's no extra parameters we have to set this  *)
  106. (* form up since its content is used as the command line (ouch)-:               *)
  107.  
  108.   if not (Reconnecting in ConnectionFlags) then
  109.     if ProgramSettingsForm.CheckBoxParameters.Checked then
  110.       try
  111.         case ProgramConnectForm.ShowModal of
  112.           mrOk: begin
  113.                 end
  114.         otherwise
  115.           ProgramConnectForm.FormShow(nil);     (* Check program path           *)
  116.           FreeAndNil(process);
  117.           exit
  118.         end
  119.       finally
  120.       end                               (* End of fresh or reconnect setup      *)
  121.     else
  122.       ProgramConnectForm.FormShow(nil);
  123.  
  124. (* We should have a good program name etc.                                      *)
  125.  
  126.   if FileExists(ProgramConnectForm.Executable) then begin
  127.     process.Executable := ProgramConnectForm.Executable;
  128.     for i := 0 to ProgramSettingsForm.MemoOptions.Lines.Count - 1 do
  129.       if Trim(ProgramSettingsForm.MemoOptions.Lines[i]) <> '' then
  130.         process.Parameters.Add(Trim(ProgramSettingsForm.MemoOptions.Lines[i]));
  131.     for i := 0 to ProgramConnectForm.MemoParameters.Lines.Count - 1 do
  132.       if Trim(ProgramConnectForm.MemoParameters.Lines[i]) <> '' then
  133.         process.Parameters.Add(Trim(ProgramConnectForm.MemoParameters.Lines[i]));
  134.     if ProgramSettingsForm.CheckBoxEnvironmentInherit.Checked then
  135.       for i := 1 to GetEnvironmentVariableCount do
  136.         process.Environment.Add(GetEnvironmentString(i));
  137.     for i := 0 to ProgramSettingsForm.MemoEnvironment.Lines.Count - 1 do
  138.       if expand(ProgramSettingsForm.MemoEnvironment.Lines[i],
  139.                                 ProgramSettingsForm.CheckBoxEnvironmentExpand.Checked) <> '' then
  140.         process.Environment.Add(expand(ProgramSettingsForm.MemoEnvironment.Lines[i],
  141.                                 ProgramSettingsForm.CheckBoxEnvironmentExpand.Checked));
  142.     if Trim(ProgramSettingsForm.LabeledEditWorkingDirectory.Text) <> '' then
  143.       process.CurrentDirectory := ProgramSettingsForm.LabeledEditWorkingDirectory.Text;
  144.     process.Options := [poUsePipes];
  145.     process.Execute;
  146.     Sleep(100);
  147.     Application.ProcessMessages;
  148.     if process.Running then
  149.       StatusBar1.Panels[DbgOnline].Text := 'Online'
  150.     else
  151.       shutdown;
  152.     LastConnectionType := ConnectionProgram
  153.   end else
  154.     shutdown;
  155.   if process = nil then
  156.     exit;
  157.  
  158. (* Assume that we've exited before getting here if things aren't OK.            *)
  159.  
  160.   ProcessObject := process;             (* Global record that the port is open  *)
  161.   MenuConnectionConnectUsingProfile.Enabled := false;
  162.   MenuConnectionConnectToLine.Enabled := false;
  163.   MenuConnectionReconnect.Enabled := false;
  164.   MenuConfigurationRJEAttachListingDisplay.Enabled := false;
  165.   MenuConfigurationRJEAttachPunchEditor.Enabled := false;
  166.   MenuConnectionAttention.Enabled := true;
  167.   MenuConnectionBreak.Enabled := SerialClientHandle <> -1;
  168.   MenuConnectionDisconnect.Enabled := true;
  169.   MenuConnectionRestartRJE.Enabled := false
  170. end { TMainForm.MenuConnectionConnectProgramClick } ;
  171.  

MarkMLl
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 04:56:03 pm
Dear ALL,

Just in an attempt to clarify my problem, I attach two screenshots of my sample application running under MS-Windows. The first shows the application's main form, and the second shows the counter program in a console window (displaying the number of lines in the file passed as argument and then waiting for user input).

Hope this helps.

With best wishes,
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 05:00:57 pm
@MarkMLI,

Thanks for your code, but is all that really necessary just for executing a program in console mode from a GUI application?  :o

Frankly, it is disappointing and disturbing to be able to do that so easily under MS-Windows but not under Linux (where it should be even simpler and better!).

With best wishes,
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 05:01:34 pm
Hope this helps.

Not in the least to be frank, since even if the child program has identical source compiling it for Linux will use different low-level libraries and API calls.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 05:02:23 pm
Thanks for your code, but is all that really necessary just for executing a program in console mode from a GUI application?  :o

No, but if you want it simplified I'd like cash up front please.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: Seenkao on July 29, 2021, 06:29:49 pm
День добрый!
Извиняюсь, но я бы посоветовал, в таких ситуациях использовать либо чисто консольное приложение, либо LCL с использованием стандартных методов.
Это не лучший подход, для подобных решений.
Используя один или другой метод по отдельности, вы изначально сокращаете возможность сбоя программы в разных операционных системах.

Google translate:
Good afternoon!
Sorry, but I would advise, in such situations, use either a purely console application or LCL using standard methods.
This is not the best approach for such solutions.
By using one method or the other separately, you initially reduce the likelihood of a program crashing on different operating systems. :)
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 08:01:42 pm
Hey Maurobio,

I think you're getting stuck on what could be called a difference of philosophy.

Let's see if I can't explain myself...

Linux, from the get go, has been planned to run binaries, no matter from where they originate. This means that they will always run,no matter if they have been initiated from a shell, or a GUI application.

Windows, from the get go, has been designed to ALWAYS have a GUI involved. Hence the fact that even cmd.exe MUST spawn a visual window in which then it runs what was asked of it.

To be honest, in my opinion, the outsider here is Windows, It's insistence that everything should have a window shown(Yes big irony it's called Windows for a reason, LOL) is a bit nonsensical.
But that's just my opinion and it won't solve your problem, so back to your problem...

So let's try and make things the same for each OS, and by that I mean, let's ask both to run our count inside their respective visual command line hosts:

If a system is well configured, it should have a wrapper for the default Terminal app.
What DetectXTerm should return is either that wrapper or the actual Terminal app itself.
Looking at the source of DetectXTerm you can see that both gnome-terminal and konsole are there and some of the older Terminal apps are also listed.

That wrapper, under modern Linux is usually x-terminal-emulator.
This is usually a symlink to a shell script that will eventually call the intended Terminal app.

On my Ubuntu 21.04 64b this is where it all resides:
Code: Bash  [Select][+][-]
  1. $ whereis x-terminal-emulator
  2. x-terminal-emulator: /usr/bin/x-terminal-emulator
Code: Bash  [Select][+][-]
  1. $ ll /usr/bin/x-terminal-emulator
  2. lrwxrwxrwx 1 root root 37 Aug 17  2017 /usr/bin/x-terminal-emulator -> /etc/alternatives/x-terminal-emulator*
Code: Bash  [Select][+][-]
  1. $ ll /etc/alternatives/x-terminal-emulator
  2. lrwxrwxrwx 1 root root 31 Aug 17  2017 /etc/alternatives/x-terminal-emulator -> /usr/bin/gnome-terminal.wrapper

That last file is the shell script that eventually calls the GNOME Terminal app and while looking at it's source I found out that you need to use the param "-e" to pass the program you want the Terminal to run.

With that in mind, why don't you try this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.   ShellProg, CmdLine, Datafile: string;
  4. begin
  5.   {$IFDEF WINDOWS}
  6.   ShellProg:= 'cmd.exe';
  7.   CmdLine:= ExtractFilePath(Application.ExeName)+'counter.exe';
  8.   {$ELSE}
  9.   ShellProg:= DetectXTerm;
  10.   CmdLine := ExtractFilePath(Application.ExeName)+'counter';
  11.   {$ENDIF}
  12.   Datafile := {ExtractFilePath(Application.ExeName)+}'lines.txt'; // Not sure it needs full path, so I'm leaving the comment in
  13.   AProcess := TProcess.Create(nil);
  14.   try
  15.     AProcess.Executable := ShellProg;
  16.     {$IFDEF WINDOWS}
  17.     AProcess.Parameters.Add('/c');
  18.     {$ELSE}
  19.     AProcess.Parameters.Add('-e');
  20.     {$ENDIF}
  21.     AProcess.Parameters.Add(CmdLine);
  22.     AProcess.Parameters.Add(Datafile);
  23.     AProcess.Options := AProcess.Options + [poWaitOnExit];
  24.     AProcess.Execute;
  25.     if AProcess.ExitCode <> 0 then
  26.       ShowMessageFmt('Error: %s reports error code %d', [CmdLine, AProcess.ExitCode]);
  27.   finally
  28.     AProcess.Free;
  29.   end;
  30. end;
  31.  

It works on my Ubuntu 21.04 64b and I was also able to make it work under wine doing a dir, cuz I don't have a C cross-compiler to Windows, only a FPC one.

Please adjust accordingly to your LUbuntu.

Hope this helps!!

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 09:27:36 pm
Hi, Gus!

Thanks a lot for your comprehensive explanation of these differences between MS-Windows and Linux.

Your code almost work. I say "almost" because, at least under MS-Windows (I have not yet tested it under Linux), it fails in two situations:


Both situations pose potentially serious problems for my application, since the 'external' program my users will be executing is a third-part application which should be installed separately, in its own path.

I will now proceed to perform tests under Linux Ubuntu and will report the results soon.

With best wishes,
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 10:31:09 pm
Windows, from the get go, has been designed to ALWAYS have a GUI involved. Hence the fact that even cmd.exe MUST spawn a visual window in which then it runs what was asked of it.

Is that /really/ true? Because I've got things like tar.exe which run entirely happily in the context of am existing cmd.exe session.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 10:37:56 pm
Dear ALL,

Based upon the suggestions by @lucamar and @Gus, I finally settled at the following 'hybrid' code, which works as expected in both Linux and MS-Windows:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.   {$IFDEF LINUX}ShellProg,{$ENDIF} CmdLine, Datafile: string;
  4. begin
  5.   {$IFDEF WINDOWS}
  6.   CmdLine := ExtractFilePath(Application.ExeName) + 'counter.exe';
  7.   {$ELSE}
  8.   ShellProg := DetectXTerm;
  9.   CmdLine := ExtractFilePath(Application.ExeName) + 'counter';
  10.   {$ENDIF}
  11.   Datafile := ExtractFilePath(Application.ExeName) + 'lines.txt';
  12.   AProcess := TProcess.Create(nil);
  13.   try
  14.     {$IFDEF LINUX}
  15.     AProcess.Executable := ShellProg;
  16.     AProcess.Parameters.Add('-e');
  17.     AProcess.Parameters.Add(CmdLine);
  18.     {$ENDIF}
  19.     {$IFDEF WINDOWS}
  20.     AProcess.Executable := CmdLine;
  21.     {$ENDIF}
  22.     AProcess.Parameters.Add(Datafile);
  23.     AProcess.Options := AProcess.Options + [poWaitOnExit];
  24.     AProcess.Execute;
  25.     if AProcess.ExitCode <> 0 then
  26.       ShowMessageFmt('Error: %s reports error code %d', [CmdLine, AProcess.ExitCode]);
  27.   finally
  28.     AProcess.Free;
  29.   end;
  30. end;

Executing a separate "shell program" under MS-Windows is not necessary and gave rise to many problems, therefore under this OS the command line can be executed directly (as per the code above).

I have not yet tested this code with my 'real' application, but in principle I can see no reason why it should not work (BTW, how many times have such words been proffered before catastrophic system failures?  ::))

Thank you very much!

With best wishes,
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 10:46:01 pm
Hey Maurobio,

Thanks a lot for your comprehensive explanation of these differences between MS-Windows and Linux.

No problem at all. I thought that this thread was going a bit sideways and it needed a bit more words to get it on track, so I put some words down ;)

Your code almost work. I say "almost" because, at least under MS-Windows (I have not yet tested it under Linux), it fails in two situations:

  • if the program to be executed (counter.exe) is in a path other than that of the application executable;
  • if the full path name of the data file is included with the name of that file

Both situations pose potentially serious problems for my application, since the 'external' program my users will be executing is a third-part application which should be installed separately, in its own path.

I will now proceed to perform tests under Linux Ubuntu and will report the results soon.

With best wishes,

While testing under Ubuntu, not wine, I tested these two cases and they all worked:

I don't remember if I tested counter lines.txt, since the executable and the text file is under the same folder as the calling binary, but that's not what worries you since the counter binary will be somewhere else in the system.

The code I provided you is using FULL path to counter binary and, if you uncomment that piece of code, you can enable the text file to be used with FULL path and it all works.

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 10:49:57 pm
Hey Mark,

Is that /really/ true? Because I've got things like tar.exe which run entirely happily in the context of am existing cmd.exe session.

Well, once the cmd.exe window is shown, it can then run any amount of commands you give it.
But this doesn't invalidate the fact that you're still looking at a Window that host's the cmd.exe, right? And to be able to run that first command, the window HAS to pop up...
On Linux, the host system(Terminal app) is optional, right?

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 29, 2021, 10:53:33 pm
Well, once the cmd.exe window is shown, it can then run any amount of commands you give it.
But this doesn't invalidate the fact that you're still looking at a Window that host's the cmd.exe, right? And to be able to run that first command, the window HAS to pop up...
On Linux, the host system(Terminal app) is optional, right?

I'm afraid that I read your "even cmd.exe MUST spawn a visual window in which then it runs what was asked of it." as implying that cmd.exe always created an additional window for a program. My apologies if I misinterpreted you.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 10:57:07 pm
Hey Maurobio,

Based upon the suggestions by @lucamar and @Gus, I finally settled at the following 'hybrid' code, which works as expected in both Linux and MS-Windows:

YAY, I'm glad you were finally able to get it working !!!

Executing a separate "shell program" under MS-Windows is not necessary and gave rise to many problems, therefore under this OS the command line can be executed directly (as per the code above).

Hummm, sorry for causing you grief with running another cmd unnecessarily!!
My intention was to make a parallel between the 2 OSs, not mess up your life and for that I apologize!!

I have not yet tested this code with my 'real' application, but in principle I can see no reason why it should not work (BTW, how many times have such words been proffered before catastrophic system failures?  ::))

LOL!!  :D

Thank you very much!

You are more than welcome!!!

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 10:59:05 pm
Hey Mark,

I'm afraid that I read your "even cmd.exe MUST spawn a visual window in which then it runs what was asked of it." as implying that cmd.exe always created an additional window for a program. My apologies if I misinterpreted you.

No need for apologies Mark!!

I've made my fair share of bad assumptions to know where you're coming from :)

All's good :)

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: maurobio on July 29, 2021, 10:59:31 pm
Dear ALL,

Your are such gentlemen! It is a honour and a privilege to be able to receive your help!

Thanks a lot for your time and patience.

With best wishes,
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 29, 2021, 11:05:37 pm
Hey Maurobio,

Your are such gentlemen! It is a honour and a privilege to be able to receive your help!

AAAwww, stop it, now you're making me all red in the face  :-[ ;)

Thanks a lot for your time and patience.

You're quite welcome. The pleasure was all mine :)

Cheers,
Gus
Title: Re: Problem running external program under Linux
Post by: maurobio on July 30, 2021, 12:52:14 am
Dear ALL,

BTW, the code provided by @Gus, with my humble adaptations, just worked fine with my 'real' application! :D

Again, thank you very much.

With best wishes,
Title: Re: Problem running external program under Linux
Post by: PascalDragon on July 30, 2021, 09:02:29 am
Windows, from the get go, has been designed to ALWAYS have a GUI involved. Hence the fact that even cmd.exe MUST spawn a visual window in which then it runs what was asked of it.

This is not quite correct. Windows evolved from DOS where the only possibility were console applications.

The header of PE/COFF files contains a field that decides the subsystem of the executable (in this case GUI vs. CUI, there are also other values that are not important for this). Applications that have the subsystem type CUI require a terminal, but not a console window, cause it's perfectly fine to execute console applications in e.g. a SSH session (when you connect to a Windows using SSH) or e.g. on the Windows IoT core variant of devices where you have either WinRT style apps or console applications. (Also when starting a process it can be requested to hide that window upon start)

TL;DR: If you start a CUI application from a process that does not have a terminal associated then Windows will automatically spawn a console window, but if a terminal is associated it will continue to use that.
Title: Re: Problem running external program under Linux
Post by: MarkMLl on July 30, 2021, 09:55:31 am
The header of PE/COFF files contains a field that decides the subsystem of the executable (in this case GUI vs. CUI, there are also other values that are not important for this).

Yes, that was one of the things I was thinking about. It could be argued that Unix-style ELF etc. are deficient in their lack of this, and that their ability to check during startup is no substitute for telling the OS what resources might be needed before attempting to bring anything into memory.

MarkMLl
Title: Re: Problem running external program under Linux
Post by: Gustavo 'Gus' Carreno on July 30, 2021, 07:21:03 pm
Hey PascalDragon,

This is not quite correct. Windows evolved from DOS where the only possibility were console applications.

I was being a bit over-simplistic in my, wrongly, generalization of the issue.
I'm that old that I should not fall into these traps of doing so much generalization, but hey, here you go, me messing it up again :)

The header of PE/COFF files contains a field that decides the subsystem of the executable (in this case GUI vs. CUI, there are also other values that are not important for this). Applications that have the subsystem type CUI require a terminal, but not a console window, cause it's perfectly fine to execute console applications in e.g. a SSH session (when you connect to a Windows using SSH) or e.g. on the Windows IoT core variant of devices where you have either WinRT style apps or console applications. (Also when starting a process it can be requested to hide that window upon start)

TL;DR: If you start a CUI application from a process that does not have a terminal associated then Windows will automatically spawn a console window, but if a terminal is associated it will continue to use that.

I was not aware of that, at all.

As per usual, many thanks PascalDragon for the trove on invaluable info!!!

On a side note, where do Windows Services fall in all this, cuz they're the only ones, well that I know of, that don't need a Window associated with, right?

Cheers,
Gus
TinyPortal © 2005-2018