-
Notifications
You must be signed in to change notification settings - Fork 1
Exec_ec
File, Folder and Read functions exec(ute)_ec(errorcode)
- exec_ec(command line)
- exec_ec(command line, current folder path)
- exec_ec(application name, command line, current folder path)
executes the command line argument and returns it's ExitCode,
It does so by calling CreateProcessA(application name, command line, NULL, NULL, TURE, 0, NULL, NULL, zeroes, zeroes) where application name is NULL when not specified, in which case the application to start is derived from the command line. Once started, command line is what the child process will see when calling GetCommandLine(). See also: Environment.cpp.
When no current folder path is specified, the current folder is inherited from the GeoDms process, which usually is set to the project folder of the last loaded configuration.
You can use such result in the construction of a storage name of a data source which guarantees that it will only be known after completion of that process.
- command with string value type
This example shows how to use the exec_ec function to make a list of files in a folder and store the resulting list in a text file, that can be used later in the process to read all files from the folder.
The CanGenerate parameter can be used in your expression to process all files, making sure the list of files or an error code is generated first.
container folderinfo
{
container impl
{
parameter<string> FileNameDirInfo := '%LocalDataProjDir%/dirinfo_' + date +'.str';
parameter<string> DirCmdOrg := Expand(., 'Dir '+ XmlDir +'/*.xml > ' + FileNameDirInfo);
parameter<string> DirCmd := Replace(DirCmdOrg, '/', '\\') + ' /B';
}
parameter<uint32> writeFileList :=
exec_ec(Expand(., '%env:ComSpec%'), '/c ' + impl/DirCmd, Expand(., '%LocalDataProjDir%'));
parameter<bool> CanGenerate := writeFileList== 0;
}
container wait_for_exec_ec
{
parameter<Int32> exitcode := exec_ec(
"python",
"C:/path/to/script.py --output C:/path/to/output.csv"
);
unit<uint32> output
StorageName = = "C:/path/to/output" + String(exitcode - exitcode) + ".csv"
StorageType = "gdal.vect"
StorageReadOnly = "True"
{
attribute<String> indicator_A;
}
}
The term String(exitcode - exitcode) always evaluates to the string "0", so it does not change the resulting file name. Its only purpose is to make the StorageName depend on exitcode: because the storage name can only be determined after exitcode is known, the GeoDMS first runs the exec_ec process (the Python script) and only then opens output and reads it. This guarantees the script has finished before its output is read.
This same mechanism is used to let the GeoDMS write an input file, run a Python script on it, and read the script's output back — all triggered automatically the moment the output is requested. The chain is:
- write the input data, e.g. as a parquet file (typed and fast for exchange with Python, see parquet);
- run the script with exec_ec, capturing its ExitCode;
- read the output, with the ExitCode woven into the output StorageName so the read waits for step 2.
container run_python
{
// 1. write the input the script reads (StorageReadOnly = "False")
unit<uint32> input := src/objecten
StorageName = "%LocalDataProjDir%/Python/temp/input.parquet"
StorageType = "gdalwrite.vect"
StorageReadOnly = "False"
{
attribute<uint32> id := src/objecten/id;
attribute<float32> oppervlakte := src/objecten/oppervlakte;
}
// 2. run the script; PropValue forces the input above to be written first
parameter<string> inputWritten := PropValue(input, 'StorageName');
parameter<int32> exitcode :=
exec_ec("python", '"%LocalDataProjDir%/Python/script.py" "' + inputWritten + '"');
// 3. read the output; the ExitCode in the StorageName makes the read wait for step 2
unit<uint32> output
StorageName = = '"%LocalDataProjDir%/Python/temp/output' + String(exitcode - exitcode) + '.parquet"'
StorageType = "gdal.vect"
StorageReadOnly = "True"
{
attribute<string> result;
}
}
See parquet for how to relate the read output domain to an already configured domain.
GeoDMS ©Object Vision BV. Source code distributed under GNU GPL-3. Documentation distributed under CC BY-SA 4.0.