How can I use script to launch an external application
a_s_lord
Posts: 33
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
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
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?
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:
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
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?
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.
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
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();