How to gracefully exit from command line error

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/11/2009 at 12:41, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   11.027 
Platform:      
Language(s) :     C++  ;

---------
Hi Everyone,

I have a plugin that parses the command line for an option and an argument to that option. Here's an example of the correct usage for the option:
  CINEMA_4D -match "*_hand_*" myscene.c4d

If the user omitted the option argument ("*_hand_*" in the example), I'd like to print an error message and exit cinema4d without loading any additional plugins and without crashing.

Is there a way to do this? Here's the current code snippet from PluginMessage, case C4DPL_COMMANDLINEARGS:

  
std::string matcher = "";  
std::string c4dFile = "";  
  
for (LONG i = 0; i < args->argc; i++)  
{  
  if (!args->argv) continue;  
  
  if ( !strcmp(args->argv,"-match") )  
  {  
      args->argv = NULL;  
      if ( (i+1) < args->argc && args->argv[i+1] )  
      {  
          const char* mstr = args->argv[i+1];  
          if (strcmp(mstr, "-"))  
          {  
             matcher = mstr;  
             args->argv[i+1] = NULL;  
             std::cerr << std::endl << "Will try to match textures with: " << matcher << std::endl;  
          }  
      }  
      if (matcher.empty())  
      {  
           std::cerr << "ERROR: Must specify a match string if using the -match option." << std::endl;  
  
           // HERE IS WHERE I WANT TO TELL C4D TO EXIT. throw is not graceful!             
           throw (-1);  
      }  
  }  

Any ideas? Thanks!

P.S., how do you enter code snippets in this fancy new RichText Editor?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/11/2009 at 22:30, xxxxxxxx wrote:

Don't know the exact context, but you should be able to send a quit message, if this is allowed there.

Generally I don't think that a plugin should exit Cinema at all. To me this looks like a bad design (what if the users would like to use Cinema w/o your plugin, do they have to deinstall then?

I'm also wondering how the user should see an error of an application that just closes.

Kabe

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/11/2009 at 23:33, xxxxxxxx wrote:

Good points, Kabe.

I would think that either a dialog which allows the user a choice to exit C4D or continue to execute it when your plugin's arguments are not met - or - a good design to avoid situations where the user is generally starting C4D and your plugin unexpectedly quits it.  In other words, a choice when your plugin finds real trouble and no interference when your plugin is not involved during C4D startup.

Also, throwing exceptions is bad.  C4D does not have any direct exception support (as far as I know from earlier versions) - there is no exception catching/handling in C4D itself.  That might explain the crashing.  You'll have to forego that exception expectation (uncaught exceptions being caught by the application).

I have no idea how to cause C4D to exit from a plugin.  There is a C4DPL_ENDPROGRAM command but not sure if it is possible (or allowed) to send it from a plugin.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/11/2009 at 03:50, xxxxxxxx wrote:

Originally posted by xxxxxxxx

I have no idea how to cause C4D to exit from a plugin.  There is a C4DPL_ENDPROGRAM command but not sure if it is possible (or allowed) to send it from a plugin.

Just tried this, CallCommand(12104) will do it - that's the Quit C4D command. Seems to work fine (tested in R10). Of course, this assumes Cinema has completed loading and the user calls the plugin. I don't know if it would work before then.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/11/2009 at 08:06, xxxxxxxx wrote:

I think he wants to preemptively quit C4D so I was looking for a way to do that.  The Quit command may or may not work if done at such an early stage.  We'll see. 🙂

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/11/2009 at 08:23, xxxxxxxx wrote:

Yes, I thought that might be a problem with that method. I've just tried it. Putting the CallCommand() in PluginStart simply hangs Cinema, and the process has to be terminated in task manager (not unexpected!). Putting it in PluginMessage, case C4DPL_COMMANDLINEARGS, doesn't seem to have any effect.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/11/2009 at 08:50, xxxxxxxx wrote:

Originally posted by xxxxxxxx

_ _ ____P.S., how do you enter code snippets in this fancy new RichText Editor?

It's done with CODE tags have a look a your first post. I edited it.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/11/2009 at 08:52, xxxxxxxx wrote:

As for the original question, I have to ask the developers about it.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 30/11/2009 at 14:58, xxxxxxxx wrote:

Oh, I'm sorry I did not provide enough information.

In this case, Cinema4D is running in batch mode (-nogui) remotely, processing hundreds of textures. It is a small part of a much larger rendering job.

Of course, I could write a script that would launch the job, first checking to make sure all command line arguments are valid. But unfortunately the code that launches Cinema4D is part of a larger system that cannot be modified at this time. Also, this would only apply if there were a problem with the command line. I'd still need a way to gracefully exit if an error occured after the command line was successfully parsed.

Currently, we throw an exception whenever an error occurs, but we *know* this isn't the correct approach (as indicated by the comment in the code snippet of the original post). The uncaught exception is handled by a post processor, which is unable to properly interpret the crash log.

We need something that will immediately exit Cinema4D with some sort of an error code.

I just saw C4DPL_ERROR in the SDK, would it be safe to send that?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 04/12/2009 at 06:34, xxxxxxxx wrote:

Please try to execute

  
CallCommand(12104);  

or

  
UWORD empty[2];  
empty[0]=empty[1]=0;  
RestartApplication(empty);  

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 04/12/2009 at 12:14, xxxxxxxx wrote:

Hi Matthias,

I tried both of the solutions that you recommended, and they both exit gracefully, which is good.

However, in both cases C4D exits with code 0. The script that started the C4D job thinks the job was successful and so it launches the next job. This is not good.

Here is a snipped from our python script:

  
cmd = 'CINEMA_4D -nogui -camspref'   
retval = os.system(cmd)   
if (retval) :   
    print 'ERROR: C4D command did not complete successfully'   
    sys.exit(1)   
else:   
    # Launch compositing job   

Is there anything I can set so that C4D exits and returns non zero to the system?

Thanks!

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 04/12/2009 at 12:16, xxxxxxxx wrote:

One other note I'd like to mention: We have the same problem when C4D errorors out during a reander (as opposed to during plugin execution). C4D prints a message that the render failed, but then exits and returns 0 to the system (instead of an error code).

Does C4D always return 0 when it exits?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 07/12/2009 at 03:48, xxxxxxxx wrote:

You can pass an exit code to RestartApplication.

  
void RestartApplication(const UWORD *param = NULL, LONG exitcode = NULL, const UWORD **path = NULL)  

cheers,
Matthias