Foro de Soporte Allplan

[Pregunta] Change Allplan Projects Dynamically via Command Line or PythonParts


Hello Allplan community,

I am currently exploring options to dynamically change Allplan projects while the application is running, either through PythonParts or command line operations. I have successfully opened Allplan directly to a specific project using the command below:

cd "C:\\Program Files\\Allplan\\Allplan\\2022\\Prg" .\\Allplan_2022.exe /l "C:\\Data\\Allplan\\2022\\Prj\\PROJECT_NAME.prj\\Project1.Dat.xml"

However, I am now looking for a way to switch projects programmatically without shutting off Allplan. I have attempted to achieve this using PythonParts, referring to the documentation section on ProjectService

https://pythonparts.allplan.com/2024/api_reference/InterfaceStubs/NemAll_Python_BaseElements/ProjectService/?h=open+project#NemAll_Python_BaseElements.ProjectService.OpenProject

Unfortunately, I am encountering challenges with the `hostName` and `doc` arguments. Could someone kindly clarify the meaning of these parameters?

Additionally, if there are alternative methods or best practices for achieving this project switching functionality programmatically, I would greatly appreciate any guidance or insights.

Thank you in advance for your assistance.

Best regards

Show most helpful answer Hide most helpful answer

Hi,

first of all, the PythonParts framework don't just "do the script from top to bottom". A python script, to be correctly understood by the PythonPart framework, has to have some functions implemented in a specific way. Those functions are called by the framework in certain situations (events). Which functions must and which can be implemented, depends on whether you want to design a standard PythonPart or an interactor PythonPart. In your code snippet, you instructed Allplan to open a project completely outside of any event. Perhaps the framework has now troubles understanding this unusual way. So first I would reccomend you to study those two articles to better understand, what the framework is actually doing with your code.

In your use-case, I would recommend designing your script as an interactor. You will have way more control, when what action will be executed.

Now to the solution of your problem: indeed starting a Python script in Allplan from the command line is possible only, when starting a new process. When Allplan is running, you cannot start a PythonPart outside of it. That is the limitation at the moment. Let us know, if that is a big deal for you, because we may consider somehow removing this limitation in the future.

If you want to design a separate desktop application, that communicates with Allplan, you can achieve this by starting a local http server with a PythonPart. This hosting PythonPart will do nothing else, as just wait for a http request, that should come from your app. However, it has to be started in Allplan manually by the user. Only after that your application can send requests to it.

You will find an example in the attachment, where the host is a PythonPart, and the client is an external C# .NET app. To try it out, start the PythonPart in Allplan first. Then start the client - it will create a cube in the model.

Best!
Bart

Adjuntos (1)

Type: application/zip
Descargado 390 veces
Size: 98,26 KiB

Hi!

hostName is the name of the server, where the project is hosted. For projects saved locally, it is just "localhost".
To get the host name of the current project, use the GetCurrentProjectNameAndHost method:

project_name, host = AllplanBaseElements.ProjectService.GetCurrentProjectNameAndHost()

To get project names and hosts of all available projects, you can try the GetAttributesFromAllProjects method. This will give you a list of all project attributes of all existing projects. The project name would be saved in the attribute 405, and the host in 403.

The result of the method GetAttributesFromAllProjects is a bit tricky in the handling, because it is a plain list of attribute IDs and values of all projects. Here is a small code snippet, that would create a list of tuples like (project_name, project_host):

        all_projects_attributes = AllplanBaseElements.ProjectAttributeService.GetAttributesFromAllProjects()
        project_names = []
        project_hosts = []

        for project_attribute in all_projects_attributes:
            if project_attribute[0] == 403:
                project_hosts.append(project_attribute[1])
            elif project_attribute[0] == 405:
                project_names.append(project_attribute[1])

        project_names_and_hosts = []

        for idx, project_name in enumerate(project_names):
            project_names_and_hosts.append((project_name, project_hosts[idx]))

Regarding doc: it is the document adapter. You get this object from the framework in various function calls. I don't know, where do you want to implement the OpenProject method. E.g. in the modify_control_properties function, you get the document adapter here as the fifth argument. Have a look on the templates in:

etc\PythonPartsFramework\PythonPartsScriptTemplates\StandardPythonPart

to see, which function gives you the document adapter argument.

Lastly, regarding OpenProject: I see, there is a bit mess with the arguments. The right order is:
1. Document adapter
2. Host name
3. Project name

like this:

        AllplanBaseElements.ProjectService.OpenProject(document,
                                                       "localhost",
                                                       "Hello Allplan! 2024")

Best,
Bart

Hello Bart,

I appreciate your prompt response. I apologize for the delayed reply as i had a busy week.

Despite your detailed response, i've encountered difficulties in utilizing PythonParts to open a project. Therefore, i opted to provide a more detailed explanation of my objective.

I'm currently developing an Allplan project opener application using Tauri. Essentially, it's a table that displays projects, allowing me to search and filter them. When i wish to open a project, i select it from the table, and the app executes shell command i already mentioned.

This works when Allplan is not running. However, i am now looking to handle changing projects from my app while Allplan is already running.

The simplest solution seems to be finding a similar shell command to change the project. Alternatively, i am considering using PythonParts. The idea is to check if the Allplan process is running and then invoke the PythonPart from the command line with the project name as an argument.

Here is a little code snippet that i tried, but unfortunately, it causes Allplan to crash. I would greatly appreciate it if you could take a moment to review it. Your assistance would be immensely valuable to me. Thank you, and have a wonderful day

Adjuntos (1)

Type: image/png
Descargado 24 veces
Size: 254,45 KiB

Hi,

first of all, the PythonParts framework don't just "do the script from top to bottom". A python script, to be correctly understood by the PythonPart framework, has to have some functions implemented in a specific way. Those functions are called by the framework in certain situations (events). Which functions must and which can be implemented, depends on whether you want to design a standard PythonPart or an interactor PythonPart. In your code snippet, you instructed Allplan to open a project completely outside of any event. Perhaps the framework has now troubles understanding this unusual way. So first I would reccomend you to study those two articles to better understand, what the framework is actually doing with your code.

In your use-case, I would recommend designing your script as an interactor. You will have way more control, when what action will be executed.

Now to the solution of your problem: indeed starting a Python script in Allplan from the command line is possible only, when starting a new process. When Allplan is running, you cannot start a PythonPart outside of it. That is the limitation at the moment. Let us know, if that is a big deal for you, because we may consider somehow removing this limitation in the future.

If you want to design a separate desktop application, that communicates with Allplan, you can achieve this by starting a local http server with a PythonPart. This hosting PythonPart will do nothing else, as just wait for a http request, that should come from your app. However, it has to be started in Allplan manually by the user. Only after that your application can send requests to it.

You will find an example in the attachment, where the host is a PythonPart, and the client is an external C# .NET app. To try it out, start the PythonPart in Allplan first. Then start the client - it will create a cube in the model.

Best!
Bart

Adjuntos (1)

Type: application/zip
Descargado 390 veces
Size: 98,26 KiB