# How to get the names of inherited projects of the actively running project on a client?

**URL:** <https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437>\
**Category:** Ignition\
**Tags:** ignition80\
**Created:** [November 9, 2020, 7:46am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437 "2020-11-09T07:46:33Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [November 9, 2020, 7:46am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/1 "2020-11-09T07:46:33Z")

</div>

I’m trying to make a script that will create a list of all Perspective Styles for the current project (and inherited projects) so that I can display a list of all styles visually. I have a global project, but in the future this might become more than just this, so I want to make it dynamic. I can get the active project name with `system.project.getProjectName()` and all projects with `system.project.getProjectNames()`, but I’m not sure how to check the inheritance structure?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 9, 2020, 4:41pm UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/2 "2020-11-09T16:41:59Z")

</div>

There’s nothing exposed to general purpose scripting, but if you know how to get a GatewayContext (check around the forums) you can call `getProjectManager()` and then from the project manager `getProjectManifests()`, which will return a dictionary of `{string: ProjectManifest}`, where each [`ProjectManifest`](http://files.inductiveautomation.com/sdk/javadoc/ignition80/8.0.14/com/inductiveautomation/ignition/common/project/ProjectManifest.html) has a `getParent()` method - with some tree-walking you can build up your inheritance structure that way.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [November 9, 2020, 5:59pm UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/3 "2020-11-09T17:59:04Z")

</div>

Thanks Paul!

This walks through each project and pulls out the styles as dictionaries with:

- projectName
- styleFullPath (directory filepath)
- styleParentPath (relative-to-project path, excluding style name)
- styleName (just the name of the style; styleParentPath + ‘/’ + styleName = the full path to the style for Ignition purposes)

The relevant part of the code to this topic is:

```auto
from com.inductiveautomation.ignition.gateway import IgnitionGateway
context = IgnitionGateway.get()
projectMgr = context.getProjectManager()
projectMfst = projectMgr.getProjectManifests()
projectName = system.project.getProjectName()
projectMfst[projectName].getParent() # this is the name of the inherited project of the active project

```

This is the full script:

```auto
def findFolderStyles(projectName, folderPath):
		import os
		import sys
		styles = []
		for root, subdirs, files in os.walk(folderPath):
			if 'resource.json' in files:
				styles.append({'projectName':projectName,
							   'styleFullPath':str(root), # this is the full directory path to the style in Windows
							   'styleParentPath':'/'.join(root.replace(folderPath,'').split('\\')[:-1]), # gets the Perspective Style path used in Ignition, excluding the style name itself 
							   'styleName':str(root.split('\\')[-1])
							   })
		return styles
	
	def findProjectStyles(projectName):
		projectParentFolder = "C:\\Program Files\\Inductive Automation\\Ignition\\data\\projects\\"
		styleClassesRelPath = "\\com.inductiveautomation.perspective\\style-classes\\"
	
		styleClassFullPath = '%s%s%s' % (projectParentFolder, projectName, styleClassesRelPath)
		
		return findFolderStyles(projectName, styleClassFullPath)
	
	def findRelevantProjectStyles():
		from com.inductiveautomation.ignition.gateway import IgnitionGateway
		context = IgnitionGateway.get()
		projectMgr = context.getProjectManager()
		projectMfst = projectMgr.getProjectManifests()
		projectName = system.project.getProjectName()
		
		styles = []
		# get the Perspective Styles defined in the current project
		styles.extend(findProjectStyles(projectName))
		
		while projectMfst[projectName].getParent() != '':
			# get the parent project
			projectName = projectMfst[projectName].getParent()
			# get the Perspective Styles defined in the parent project 
			styles.extend(findProjectStyles(projectName))
		return styles
	
	styles = findRelevantProjectStyles()
	udtInstances = styles
	self.getChild("FlexRepeater").props.instances = udtInstances

```

 ![Perspective Styles Lister](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/0/e0bac7ed09b7e73b5ad7f803cd3b4240c9a51ffd.gif)

---

<div class="post-metadata">

**Author:** ![jeremy.lecoutre](https://avatars.discourse-cdn.com/v4/letter/j/3e96dc/32.png) [@jeremy.lecoutre](https://forum.inductiveautomation.com/u/jeremy.lecoutre)\
**Post date:** [April 9, 2022, 2:53pm UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/4 "2022-04-09T14:53:40Z")

</div>

Hello,

This is an old topic but just to share a more convenient method witch not browse windows files.

```auto
def findRelevantProjectStyles():
		from com.inductiveautomation.ignition.gateway import IgnitionGateway
		
		styles = []
	
		projectName = system.util.getProjectName()
		context = IgnitionGateway.get()
		projectManager = context.getProjectManager()
		runtimeProject = projectManager.getProject(projectName).get()
	
		# Retrieve all ressources from project and its parents
		allProjectResources = runtimeProject.getAllResources()
		for projectResourceId,immutableProjectResource in allProjectResources.items():
			ressourceType = immutableProjectResource.getResourceType()
			typeId = ressourceType.getTypeId()
			# Check if resource was a style-classes
			if "style-classes" == typeId:
				if not immutableProjectResource.isFolder():
					styleFullPath = immutableProjectResource.getFolderPath()
					styles.append({'projectName':immutableProjectResource.getProjectName(),
								   'styleFullPath':styleFullPath, # this is the full directory path to the style in Perspective Style
								   'styleParentPath':styleFullPath.rsplit("/",1)[0], # gets the Perspective Style path used in Ignition, excluding the style name itself 
								   'styleName':immutableProjectResource.getResourceName()
								   })
		return styles

```

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [April 9, 2022, 7:52pm UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/5 "2022-04-09T19:52:43Z")

</div>

Very nice, thanks for sharing!

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [June 2, 2022, 6:19am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/6 "2022-06-02T06:19:25Z")

</div>

I’m new to this, Can somebody help me how to use these functions as I’m facing difficulty, any docs related to this, how that import gateway is working what all things are available inside that, how to check that, how it can be utilized, suppose I had multiple gateways then how I can get details of those gateway by using this scripts. Can someone please help me on that.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 2, 2022, 6:35am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/7 "2022-06-02T06:35:37Z")

</div>

You’ll need to run the function from the gateway scope(e.g. from a tag change script, perspective component event handler/script transform, gateway timer script, etc.).

To run it on multiple gateways from one, you would need to have them all attached on the GAN (gateway network) and then you would need to use `system.util.sendRequest` to execute a function on the remote gateways.

Use this as a reference for the api classes etc. Note though that a lot of it is not publicly documented so most of the code on the forums dealing with this come from IA staff. Also note that using these methods is therefore completely unsupported (unless you get help on the forum) and is prone to breaking in future upgrades.  
[https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/index.html](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/index.html)

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [June 2, 2022, 10:52am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/8 "2022-06-02T10:52:29Z")

</div>

Thank you very much @nminchin really appreciate the time you spend for this detailed reply. I saw that document, but can’t understand that. there is an option to import ignition gateway, so what all functions are available in there. suppose I found some other script from this forum itself like

from com.inductiveautomation.ignition.gateway import IgnitionGateway  
projectNames = list(IgnitionGateway.get().getProjectManager().projectNames)

I’m not understanding how it is working.From where that list is getting. I checked that link, it’s getting hard for me to find how it is working, can you help me with an example if possible how to read from that url for several packages which is available. I’m a noobie. Can u please help.?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 2, 2022, 12:04pm UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/9 "2022-06-02T12:04:52Z")

</div>

> [@John\_S1](#):
>
> I’m a noobie.

Hi John. You are going to struggle a bit because you are asking for documentation for an object that IA has _deliberately_ chosen _not_ to document. You are also asking about access to information for which there is _ **no supported method** _. People are trying to help you via _ **unsupported** _ methods, but they tend to be complicated and there is no magic wand.

Nick linked to the SDK documentation, which is the public "schematic" for Ignition's "control panel". It is bog-standard JavaDoc. If you learn to read that "schematic", you'll be able to infer a great deal about the undocumented parts. Reading JavaDoc is easiest if you have experience with Java. People who use jython a great deal (experienced Ignition script writers) often pick it up too, as jython permits using it's environment's java objects in a form close to native python.

Consider reading every topic in this search:

[https://forum.inductiveautomation.com/search?q=import%20IgnitionGateway](https://forum.inductiveautomation.com/search?q=import%20IgnitionGateway)

They are all examples of the use of this particular unsupported platform object.

Another source of information would be the `introspect` function from my `inspect.py` helper library. These topics discuss it:

[https://forum.inductiveautomation.com/search?q=inspect.py](https://forum.inductiveautomation.com/search?q=inspect.py)

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 3, 2022, 2:10am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/10 "2022-06-03T02:10:49Z")

</div>

> [@John\_S1](#):
>
> projectNames = list(IgnitionGateway.get().getProjectManager().projectNames)

For this particular line, look at:

**IgnitionGateway** -\> GatewayContext?:  
[https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/model/GatewayContext.html](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/model/GatewayContext.html)

**get()** -\> GatewayContext  
No idea about this one..

**getProjectManager()** -\> ProjectManager  
[https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/project/ProjectManager.html](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/project/ProjectManager.html)

**projectNames** -\> list of strings:  
[https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/project/ProjectManagerBase.html#getProjectNames()](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/project/ProjectManagerBase.html#getProjectNames())

Also FYI, I don't understand the hows or the whys, but JavaBeans something or rather (that's the technical term) means that a Java getter and setter in Jython can be called without the get/set in the method name. But only sometimes.... @pturmel @paul-griffith?  
Q's:

1. Why can `getProjectNames` be subd as `projectNames`  
but `getProjectManager()` can't be subd as `projectManager()`? but it can be subd for `projectManager` without the brackets? (it seems you can't use the method-without-the-get/set if you include args or brackets?)  
e.g. ` runtimeProject = projectManager.project(projectName).get()` doesn't work with `project(projectName)` it has to be `getProject(projectName)`
2. Also what's the `get()` for in `IgnitionGateway.get()`?
3. Is it possible to inadvertently spawn another IgnitionGateway from script?

I probably should have asked these questions a long time ago...

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [June 3, 2022, 3:46am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/11 "2022-06-03T03:46:49Z")

</div>

Thank you very much for the time that you spend. I will definitely check. Thank you.

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [June 3, 2022, 3:48am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/12 "2022-06-03T03:48:12Z")

</div>

Superb, Thank you for that detailed explanation, now I will try to figure that around. superb guys. thank you for the support. I’m really loving this forum.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 3, 2022, 4:30am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/13 "2022-06-03T04:30:09Z")

</div>

> [@John\_S1](#):
>
> I’m really loving this forum

One of the best parts of Ignition imo! Compare Ignition's forum to other SCADA forums which are a pile of garbage from the 1900's 😆 You also get the devs always on here which is absolutely invaluable! But really, any question is fair game and you're likely to get a response within the day at least, if not within a few minutes or hours, depending on timezones. And the reason for that is that Ignitioners tend to be a passionate bunch since we're actually excited to use a product that wasn't obsoleted 15 years ago 🙂

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 3, 2022, 11:57am UTC](https://forum.inductiveautomation.com/t/how-to-get-the-names-of-inherited-projects-of-the-actively-running-project-on-a-client/40437/14 "2022-06-03T11:57:03Z")

</div>

1. `getProjectNames` is property name that yields a method. You invoke methods using the parentheses _operator_. It’s name follows the NetBeans rule for a getter, so Jython injects `projectNames` as a named property that yields the _result_ of the method. (The latter is one less step for the interpreter, so will run slightly faster.)

2. `IgnitionGateway` is a class. You can’t instantiate it yourself. `.get()` is a static method that retrieves the **singleton** instance that the platform creates during startup. Remember, this is undocumented, unsupported stuff, and the singleton pattern is an implementation detail. You just need to know that you have to work with an **instance** , not a class.

3. No, the constructor is private, IIRC.
