Managing SCIA application
ABSTRACT
In this article, you will learn:
- how to prepare the environment for your SCIA API based app
- how to run SCIA Engineer, open a project and send a structural analysis model to it
Preparation steps
Before starting SCIA Engineer with Open API, you need to introduce preparation steps to ensure a clean and reliable environment
Establish SCIA paths
To initialize the environment, you'll need two paths:
- the installation path of SCIA Engineer (by default
\Program Files\SCI\Engineer$$.$where$$.$is the major and minor version number, like25.0). - the temporary path for keeping intermediary data. It's important for it to be empty before each run of your app.
Good idea is to read both paths from the registry:
| Path | Entry in the Windows registry |
|---|---|
| Installation path | HKEY_CURRENT_USER\Software\SCIA\ESA\{{your_version}}\Admin\Dir\SYSTEM |
| Temp path | HKEY_CURRENT_USER\Software\SCIA\ESA\{{your_version}}\Admin\Dir\TEMP |
Here's an example of getting the installation path:
using Microsoft.Win32
private string GetAppPath(string version)
{
string registryPath = $@"Software\SCIA\ESA\{version}\Admin\Dir";
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(registryPath))
{
if (key != null)
{
object systemValue = key.GetValue("SYSTEM");
if (systemValue != null)
{
return systemValue.ToString();
}
}
}
throw new InvalidOperationException($"Registry key {registryPath} not found.");
}
Note
Have a look at the implementation in SciaEnvironmentManager.cs in our example app.
Assembly Resolution
The DLLs of SCIA OpenAPI are located in SCIA installation folder, but your app executable is probably located somewhere else. This makes it difficult for the .NET assembly resolver to find them. Therefore, you need to define this method:
private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
try
{
string dllName = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
string dllFullPath = Path.Combine(_sciaEngineerPath, dllName);
if (!File.Exists(dllFullPath))
{
dllFullPath = Path.Combine(_sciaEngineerPath, "OpenAPI_dll", dllName);
}
if (!File.Exists(dllFullPath))
{
return null;
}
return Assembly.LoadFrom(dllFullPath);
}
catch (Exception ex)
{
Console.WriteLine($"Failed to resolve assembly {args.Name}: {ex.Message}");
return null;
}
}
And register it to the AssemblyResolve event at the start of your app:
using System
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
It looks for the Open API DLLs in SCIA installation location (or if not found there, in the subfolder OpenAPI_dll)
and loads them. If your .exe is located in the SCIA installation directory, you don't need this custom
assembly resolver.
Note
Have a look at the implementation in SciaAssemblyResolver.cs in our example app.
Clean-up from previous runs
Before starting a new session, do some clean-up to just to make sure, there are no left-overs after previous runs of your application.
First, terminate any leftover SCIA Engineer processes. These are named like EsaStartupScreen
or SciaEngineer.
Second, remove any files from the temporary directory to avoid interference from previous runs.
Note
Have a look at the implementation of KillOrphanRuns() in
SciaProcessManager.cs
and at DeleteTemp() in SciaEnvironmentManager.cs
in our example app.
Running SCIA Engineer
SCIA Engineer is started and managed within a disposable scope using SCIA.OpenAPI.Environment.
This ensures proper resource management and clean shutdown:
Initialize using the installation path, temporary path (we established them in the first preparation step) and required API version:
using (SCIA.OpenAPI.Environment env = new SCIA.OpenAPI.Environment(installationPath, tempPath, "1.0.0.0"))
{
// Start SCIA Engineer in GUI mode
if (!env.RunSCIAEngineer(SCIA.OpenAPI.Environment.GuiMode.ShowWindowShow))
{
Console.WriteLine("Failed to start SCIA Engineer");
return;
}
// ... further operations ...
}
The environment object encapsulates the connection to SCIA Engineer and should always be disposed after use.
Opening an empty project template
To work with a new project, you must open an empty project template (.esa file). You can either
create one yourself manually or call
SciaFileGetter.PrepareBasicEmptyFile()
to generate one during the app runtime:
Note
It is recommended to prepare your own template file with the desired settings regarding structural analysis
standards, as PrepareBasicEmptyFile()
does not offer any options in this regard. Remember, that the property
NationalCode in your ADM model is not
considered at the moment!
Then, call OpenProject method of the environment to
load the template into SCIA Engineer.
SciaFileGetter fileGetter = new SciaFileGetter();
projectFilePath = fileGetter.PrepareBasicEmptyFile(tempPath);
project = env.OpenProject(projectFilePath);
project holds an instance of EsaProject. A project has exactly one model
stored in the Model property. It represents the structural
analysis model in SCIA Engineer. You can now proceed to...
Sending as analysis model to SCIA Engineer
Now you can start populating the Model property with structural
analysis elements (loads, beams, surfaces, etc.) from your ADM model (see how to create one).
The Model property is an instance of Structure
and has a method CreateAdmObject()
for adding an ADM analysis element(s).
On the other hand, ADM model is an instance of [AnalysisModel] and implements the IEnumberable interface. So you
can add each element from ADM one-by-one to the SCIA internal Structure
like:
foreach (IAnalysisObject admObject in admModel)
{
ResultOfPartialAddToAnalysisModel result = project.Model.CreateAdmObject(admObject);
if (result.PartialAddResult.Status != AdmChangeStatus.Ok)
{
Console.WriteLine($"Error adding object {admObject.Name} to model: {result.PartialAddResult.Errors}");
}
}
At the end, call RefreshModel_ToSCIAEngineer()
to transfer the analysis model to SCIA Engineer. After this step, you should be able to see the entire
model in SCIA UI (if your application runs with visible SCIA UI).
This step makes the model available for calculation and further operations within SCIA Engineer.