How can I use script to launch an external application

a_s_lorda_s_lord Posts: 33
edited December 1969 in Daz Script Developer Discussion

I've written a little utility (in VB) and compiled it as an executable (ie "dsleditor.exe").

How can I make a daz studio script to launch that executable, or other apps?


Comments

  • rbtwhizrbtwhiz Posts: 2,249
    edited May 2015

    Two ways. One more involved than the other.

    1.) Use DzApp::showURL() and allow the OS to handle the file in whatever way the OS is configured to handle files of a given type. See this thread for an example and related discussion.

    2.) Use DzProcess; a Q3Process wrapper. DzProcess hasn't been updated to wrap QProcess due to a few backward/forward compatibility issues that need to be resolved first. You'll find an example of its use in the Render To RIB sample.

    -Rob

    Post edited by rbtwhiz on
  • a_s_lorda_s_lord Posts: 33
    edited December 1969

    Thank you. I'm one step further in my knowledge that it can be done.
    I'm afraid that you might have to be more patient with me, as I have only dabbled with DAZ Scripts. I would very much appreciate it if you would help me walk through what I am sure is a simple process.

    can I first ask if the effective command will look something like:

    App.showURL(String( "file:///c:/MyApp.exe" ))


    Will some kind of "run" statement be required?

  • rbtwhizrbtwhiz Posts: 2,249
    edited June 2015

    As you are not using substitution to construct the path, you can simplify the syntax by omitting the encapsulating "String()" and just use the string literal like so:

    App.showURL( “file:///c:/MyApp.exe” );

    DzApp::showURL() "opens" the specified path, assuming that is what the OS is still configured to do (the default), so it is effectively the "run" statement. One thing to keep in mind, however, is that the statement is executed and the script continues. It doesn't wait for any kind of response. The statement is non-blocking. So, if your aim is interprocess communication rather than simply "open", you'll need to use the DzProcess route.

    -Rob

    Post edited by rbtwhiz on
  • a_s_lorda_s_lord Posts: 33
    edited December 1969

    Yes thanks Rob, that worked! It opens a world of possibilities.

    I take it then that DzProcess would allow me to return some kind of parameter, or suspend DAZ execution until the called process sends some signal/finishes?

  • Richard HaseltineRichard Haseltine Posts: 100,458
    edited December 1969

    DzProcess has details in the DS 3 Scripting docs, which are available in the DS 3 section of the Wiki. Of course there may have been updates for DS 4 - I don't know - but it should provide a starting point.

  • rbtwhizrbtwhiz Posts: 2,249
    edited December 1969

    a.s.lord said:
    I take it then that DzProcess would allow me to return some kind of parameter, or suspend DAZ execution until the called process sends some signal/finishes?

    Yes, DzProcess provides access to standard in/out/error, as well as starting/launching and terminating/exiting. The Render To RIB sample that I linked to in my initial response shows how to block the script from continuing and wait for the process to respond/exit. Scroll to the end of the sample to see it .

    Of course there may have been updates for DS 4...

    DzProcess is posted in the Object Index; see my initial response. I converted and posted it shortly before I responded. I also started on a sample that shows how to use it for asynchronous inter-process communication, rather than one-off execution as it is used in the Render To RIB sample, but encountered a problem and didn't want to delay my response until I had more time to figure out what was happening with it.

    -Rob

  • a_s_lorda_s_lord Posts: 33
    edited December 1969

    Thanks, I'm making some sense of the Render to RIB example. Its quite long and C like syntax looses me (hence wanting to call stuff I write in VB and call from script). So, to clarify - is this the bit you were referring to? What critical bit would be required to run/resume after "c:/MyApp.exe", simplifying as much as possible?


    DsActions.prototype.begin = function()
    {
    setBusyCursor();

    // If we're collecting assets and the path is valid
    if( bCollect && oFile.exists() ){
    // Create a new dir
    var oDir = new DzDir( oFile.path() );

    // Construct the name of a sub-directory to collect into
    var sCollectDir = String( "%1_collected" ).arg( oFile.baseName() );

    // If the sub-directory is successfully created
    if( oDir.mkdir( sCollectDir ) ){
    // Change to the created directory
    oDir.cd( String( "%1/%2" ).arg( oDir.absPath() ).arg( sCollectDir ) );
    }


    // Create a new process
    this.oProcess = new DzProcess();

    // Set the communication flags for the process
    this.oProcess.communication = DzProcess.Stdin | DzProcess.Stdout | DzProcess.Stderr;


    // Set the working directory
    this.oProcess.workingDirectory = App.getUtilitiesPath();

    // Connect to recieve standard output
    connect( this.oProcess, "readyReadStdout()", this, "readStdout" );

    // Connect to recieve standard error
    connect( this.oProcess, "readyReadStderr()", this, "readStderr" );



    // Create an array of arguments
    var aProcessArgs = [
    String( "%1/%2" ).arg( this.oProcess.workingDirectory ).arg( "ribdepends" ),
    "-noinit",
    "-package",
    oDir.absPath(),
    oFile.absFileName()
    ];

    // Assign the arguments
    this.oProcess.arguments = aProcessArgs;

    // If starting the process fails IS THIS WHERE THE PROCESS IS CALLED?
    if( !this.oProcess.start() ){
    // Inform the user
    MessageBox.critical( qsTr("Could not start the process."), qsTr("Fatal Error"), qsTr("&OK;") );
    }

    // Wait for the process to exit;
    // Otherwise the script will complete and in cleaning up, the process object
    // will be destroyed before said process can actually do anything
    while( this.oProcess.running ){
    // Allow the application to update
    processEvents();
    }

    }


    // Let the user know we're done
    clearBusyCursor();

Sign In or Register to comment.