Progress bar for shell commands?

Hi,
when using a Xojo shell (mode = 0) to execute a ditto command - is it possible to display a progress bar indicating the progress?

Or at least find out when the command has completed?

Thanks.

A simple dim of the shell says absolutely nothing, sorry… What is the ditto command you are executing? On which kind of file(s) ? Does the processing really take that much time that a ProgressBar is needed ?

From what I see, copying a directory for instance with the -V option lists every file. Using Shell in asynchronous mode you get every file listed in the DataAvailable event.

So what you do is use FolderItem.Count in the origin folder to know how many files there are, then use that as Maximum for the ProgressBar, and each time a new file appears in DataAvailable, push the ProgressBar with one.

IsRunning will tell you when the shell is complete.

If you use the synchronous mode, the shell is complete when execution resumes after execute.

http://documentation.xojo.com/index.php/shell

I know you usually like an already made project, and have no doubt some good souls will do it for you, but this is the principle.

Michel,
Thank you for the advice.

Not quite sure what I did to deserve that last line, but hey ho :slight_smile:

Thank you.

One other thing - you MUST use a Mode 1 or Mode 2 value and do a Do - Loop Until loop after the Execute command if you want to update the progress bar. Otherwise, you won’t see any output from the terminal until the task completes.

For example:

  Dim theShell As new Shell
  theShell.Mode = 1
  theShell.Execute theCommand
  Do
    theShell.Poll
    // handle the output you're monitoring
    App.DoEvents
  Loop Until Not theShell.IsRunning

Of course, App.DoEvents should be replaced with GUI safe code in a Desktop app, but the rest is compatible for all non-iOS platforms.

[quote=195604:@Tim Jones]One other thing - you MUST use a Mode 1 or Mode 2 value and do a Do - Loop Until loop after the Execute command if you want to update the progress bar. Otherwise, you won’t see any output from the terminal until the task completes.

For example:

  Dim theShell As new Shell
  theShell.Mode = 1
  theShell.Execute theCommand
  Do
    theShell.Poll
    // handle the output you're monitoring
    App.DoEvents
  Loop Until Not theShell.IsRunning

Of course, App.DoEvents should be replaced with GUI safe code in a Desktop app, but the rest is compatible for all non-iOS platforms.[/quote]

Tim, I hate to contradict, but polling the shell is unnecessary in mode 1, since the DataAvailable event fires whenever a new burst of data arrives. In the case of Ditto used to copy a folder content, that is each time a new file is copied.

Same thing for the loop Until Not theShell.IsRunning, totally unnecessary because the Completed event fires when the command is complete.

What you posted maybe valid for a synchronous shell…

Michel,

Unfortunately, the DataAvailable and Completed events aren’t available directly when you create a Shell object using the Dim theShell As new Shell manner, therefore, the additional bits are necessary.

DataAvailable and Completed are only available if you create a Shell object in your project and then instantiate it.

You can use addhandler to get these events without subclassing the shell object.

[quote=195619:@Tim Jones]Michel,

Unfortunately, the DataAvailable and Completed events aren’t available directly when you create a Shell object using the Dim theShell As new Shell manner, therefore, the additional bits are necessary.

DataAvailable and Completed are only available if you create a Shell object in your project and then instantiate it.[/quote]

How difficult is it to insert a shell class in a project, then drag an instance over the window ?

I am a bit annoyed when I see an asynchronous process such as mode 1 treated as a synchronous one with polling. It is like using procedural thinking with event driven languages. Sorry.

Now since I knew in the first place it would end up like that (hence my last line, he ho), here is the right way to do it, IMHO.

https://www.dropbox.com/s/qrsdrvyh55z0bb5/ditto.xojo_binary_project?dl=0

Mind you, here I have only 102 files in my picture folder, so it takes about half a second for the ditto to complete. Hardly a good use for a progressbar :wink:

The completed event never fires, though. And since the shell does not get a prompt, it cannot be used to know the command has completed. But since the program counts the number of files to set the progressBar max, one could assume that when it reaches the max, the command is complete.

IsRunning remains true no matter what. I guess only closing the shell would change that.

That is a fine method when you are dealing with one set of methods for the shell that is used over and over - and that is what I use in such cases. However, you misunderstand the purpose of that simple example - sometimes you need to do a simple task or multiple simple tasks. In one of my projects where I must run around 120 shell processes, it would become rather bloated in the code to create 120 Shell object instances because the Execute and processing code is dramatically different for each.

And as you state, your comment, your method is correct in your humble opinion. Remember, if you ask 50 coders how to accomplish a task, you’ll get 65 different answers - all of them correct in their own mechanism and purpose (Wayne’s comment about AddHandler being one of the different answers :slight_smile: )

I will just add that if the Completed event is not firing for you, I would file a bug report on your version of Xojo. I can run your code and the Completed event fires properly here under Xojo 15r2.2.

[quote=195741:@Tim Jones]That is a fine method when you are dealing with one set of methods for the shell that is used over and over - and that is what I use in such cases. However, you misunderstand the purpose of that simple example - sometimes you need to do a simple task or multiple simple tasks. In one of my projects where I must run around 120 shell processes, it would become rather bloated in the code to create 120 Shell object instances because the Execute and processing code is dramatically different for each.

And as you state, your comment, your method is correct in your humble opinion. Remember, if you ask 50 coders how to accomplish a task, you’ll get 65 different answers - all of them correct in their own mechanism and purpose (Wayne’s comment about AddHandler being one of the different answers :slight_smile: )

I will just add that if the Completed event is not firing for you, I would file a bug report on your version of Xojo. I can run your code and the Completed event fires properly here under Xojo 15r2.2.[/quote]

Tim, indeed there are many ways to program and none is neither perfect nor the only one. I use shell extensively as well, maybe not 120 at a time, though. Most often a mode 0 is fine.

In this particular instance, since Richard wanted expressly a ProgressBar, and because the UI does not update during an event, I do feel using DataAvailable is the best way to have a smooth result. A tight loop polling would probably require doevents to allow the bar to update.

My point was even more to introduce Richard to the correct way to use an asynchronous process, since what he wanted to obtain was not possible, as far as I know, with a synchronous shell. I maybe wrong, but I tend to regard event driven programming as vastly superior to loop polling. It makes little sense to go back to prehistory when Xojo provides a seamless and modern way for that particular problem.

I was careful to keep that as my own perspective and you can program the way you want. If it works for you, fine. I come from an era when the luxury of asynchronous shell did not exist, please allow a dinosaur to prefer modernity.

The Completed event does fire, but after a considerable delay, under 10.10.3. Or if one quits the program. Must be a time out, but since it is not possible to set it in OS X…

Once again, I was just trying to show Richard what I believe is the right way to go. He may need to file a bug report if he cannot live without the Completed event. That is, if he has not forgotten that whole topic entirely by now…

What topic??? :slight_smile:
I eventually decided against a progress bar. Far too much hassle, for such a small gimmick :slight_smile:

The one you initiated in this thread. Having a progressbar for a shell command. You may have changed your mind since…