Tutorial: System.launchExternalProcess

System.launchExternalProcess

Runs an executable or batch file. If an unused UUID is provided in options, it will be used. If no UUID is provided, OpenFin will assign one. This api has an enhanced permission set to make it less dangerous. So application owners can only allow to launch the assets owned by the application, the enabled downloaded files or the restricted executables.

Note: Since appAssets relies on the RVM, which is missing on MAC_OS, 'alias' is not available. Instead provide the full path e.g. /Applications/Calculator.app/Contents/MacOS/Calculator.

Example

Basic Example

fin.System.launchExternalProcess({
    path: 'notepad',
    arguments: '',
    listener: function (result) {
        console.log('the exit code', result.exitCode);
    }
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.log(error);
});

Promise resolution

//This response has the following shape:
{
    uuid: "FB3E6E36-0976-4C2B-9A09-FB2E54D2F1BB" // The mapped UUID which identifies the launched process
}

Listener callback

//This response has the following shape:
{
    topic: "exited", // Or "released" on a call to releaseExternalProcess
    uuid: "FB3E6E36-0976-4C2B-9A09-FB2E54D2F1BB", // The mapped UUID which identifies the launched process
    exitCode: 0 // Process exit code
}

Example specifying a lifetime for an external process

By specifying a lifetime, an external process can live as long the window/application that launched it or persist after the application exits. The default value is null, which is equivalent to 'persist', meaning the process lives on after the application exits.

fin.System.launchExternalProcess({
    path: 'notepad',
    arguments: '',
    listener: (result) => {
        console.log('the exit code', result.exitCode);
    },
    lifetime: 'window'
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.log(error);
});

Note: A process that exits when the window/application exits cannot be released via fin.desktop.System.releaseExternalProcess.

example specifying a cwd for an external process

By specifying a cwd, it will set current working directory when launching an external process.

fin.System.launchExternalProcess({
    path: 'cmd.exe',
    cwd: 'c:\\temp',
    arguments: '',
    listener: (result) => {
        console.log('the exit code', result.exitCode);
    }
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.log(error);
});

Example using an alias from app.json appAssets property

"appAssets": [
    {
        "src": "exe.zip",
        "alias": "myApp",
        "version": "4.12.8",
        "target": "myApp.exe",
        "args": "a b c d"
    },
]
/*
 * When called, if no arguments are passed then the arguments (if any)
 * are taken from the 'app.json' file, from the  'args' parameter
 * of the 'appAssets' Object with the relevant 'alias'.
 */
fin.System.launchExternalProcess({
    //Additionally note that the executable found in the zip file specified in appAssets
    //will default to the one mentioned by appAssets.target
    //If the the path below refers to a specific path it will override this default
    alias: 'myApp',
    listener: (result) => {
        console.log('the exit code', result.exitCode);
    }
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.logerror;
});

Example using an alias but overriding the arguments

"appAssets": [
    {
        "src": "exe.zip",
        "alias": "myApp",
        "version": "4.12.8",
        "target": "myApp.exe",
        "args": "a b c d"
    },
]
/*
 * If 'arguments' is passed as a parameter it takes precedence
 * over any 'args' set in the 'app.json'.
 */
fin.System.launchExternalProcess({
    alias: 'myApp',
    arguments: 'e f g',
    listener: (result) => {
        console.log('the exit code', result.exitCode);
    }
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.logerror;
});

Certificate Validation

It is now possible to optionally perform any combination of the following certificate checks against an absolute target via fin.desktop.System.launchExternalProcess().

"certificate": {
    "serial": "3c a5 ...",                        // A hex string with or without spaces
    "subject": "O=OpenFin INC., L=New York, ...", // An internally tokenized and comma delimited string allowing partial or full checks of the subject fields
    "publickey": "3c a5 ...",                     // A hex string with or without spaces
    "thumbprint": "3c a5 ...",                    // A hex string with or without spaces
    "trusted": true                               // A boolean indicating that the certificate is trusted and not revoked
}

Providing this information as part of the default configurations for assets in an application's manifest will be added in a future RVM update.

fin.System.launchExternalProcess({
    path: 'C:\\Users\\ExampleUser\\AppData\\Local\\OpenFin\\OpenFinRVM.exe',
    arguments: '--version',
    certificate: {
        trusted: true,
        subject: 'O=OpenFin INC., L=New York, S=NY, C=US',
        thumbprint: '‎3c a5 28 19 83 05 fe 69 88 e6 8f 4b 3a af c5 c5 1b 07 80 5b'
    },
    listener: (result) => {
        console.log('the exit code', result.exitCode);
    }
}).then(processIdentity => {
    console.log(processIdentity);
}).catch(error => {
    console.logerror;
});

Example launching a file downloaded by the user

It is possible to launch files that have been downloaded by the user by listening to the window file-download-completed event and using the fileUuid provided by the event.

const win = fin.Window.getCurrentSync();
win.addListener('file-download-completed', (evt) => {
    if (evt.state === 'completed') {
        fin.System.launchExternalProcess({
            fileUuid: evt.fileUuid,
            arguments: '',
            listener: (result) => {
                console.log('the exit code', result.exitCode);
            }
        }).then(processIdentity => {
            console.log(processIdentity);
        }).catch(error => {
            console.logerror;
        });
    }
});

Permission Definition Examples: Launching assets specified in the app manifest

Sample appAssets section in app.json

    "appAssets": [ 
        { 
            "src": "http://filesamples.com/exe.zip",
            "alias": "myApp",
            "version": "4.12.8",
            "target": "myApp.exe",
            "args": "a b c d" 
        },
        { 
            "src": "http://examples.com/exe.zip",
            "alias": "myApp2",
            "version": "5.12.8",
            "target": "myApp2.exe",
            "args": "a b c" 
        }
    ]

This permission allows for launching of all assets specified in the above appAssets section. ("myApp" and "myApp2")

    "permissions": {
       "System": {
           "launchExternalProcess": {
                "enabled": true,
                "assets": {
                    "enabled": true
                }
            }
       }
    }

This permission allows for launching of only the "myApp" asset in the above appAssets section, as defined in srcRules.

    "permissions": {
       "System": {
           "launchExternalProcess": {
                "enabled": true,
                "assets": {
                    "enabled": true
                    "srcRules": [
                        {
                            "match": [
                                "*://filesamples.com/*"
                            ],
                            "behavior": "allow"                        
                        },
                        {
                            "match": [
                                "<all_urls>"
                            ],
                            "behavior": "block"                            
                        }
                    ]
                }
            }
       }
    }

Permission Definition Examples: Launching downloaded files

    "permissions": {
       "System": {
           "launchExternalProcess": {
                "enabled": true,
                "downloads": {
                    "enabled": true
                }
            }
       }
    }

Permission Definition Examples: Launching executables

This permission allows to launch all the executables.

    "permissions": {
       "System": {
           "launchExternalProcess": {
                "enabled": true,
                "executables": {
                    "enabled": true
                }
            }
       }
    }

This permission only allows launching of executables whose file paths match the corresponding pathRules.

    "permissions": {
       "System": {
           "launchExternalProcess": {
                "enabled": true,
                "executables": {
                    "enabled": true
                    "pathRules": [
                        {
                            "match": [
                                "*/Windows/System32/*.exe"
                            ],
                            "behavior": "allow"                        
                        },
                        {
                            "match": [
                                "*.exe"
                            ],
                            "behavior": "block"                            
                        }
                    ]
                }
            }
       }
    }