# Scan File System

**URL:** <https://forum.inductiveautomation.com/t/scan-file-system/111455>\
**Category:** Module Development\
**Tags:** ignition83\
**Created:** [October 14, 2025, 8:34pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455 "2025-10-14T20:34:14Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 14, 2025, 8:34pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/1 "2025-10-14T20:34:14Z")

</div>

How do I call **Scan File System** in Gateway Hook via **code**?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 14, 2025, 8:56pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/2 "2025-10-14T20:56:32Z")

</div>

If you have a `GatewayContext`, then:

```python
context.getProjectManager().requestScan();

```

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 14, 2025, 9:02pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/3 "2025-10-14T21:02:54Z")

</div>

In version 8.3, this code only scans projects and does not scan resources such as theme and font.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 14, 2025, 9:05pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/4 "2025-10-14T21:05:00Z")

</div>

Ah, also:

```python
context.getConfigurationManager().requestScan();

```

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 14, 2025, 9:18pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/5 "2025-10-14T21:18:16Z")

</div>

I tried this too, it didn't work.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 14, 2025, 9:19pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/6 "2025-10-14T21:19:50Z")

</div>

You’ll have to better define what you’ve changed and what your expectations are.

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 14, 2025, 9:27pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/7 "2025-10-14T21:27:15Z")

</div>

> I have added a few custom themes and fonts to my module. After installing the module and the initial Gateway restart, I noticed that the themes and fonts are not automatically detected. I have to manually trigger a file system scan to make them available.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 14, 2025, 9:43pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/8 "2025-10-14T21:43:08Z")

</div>

Expand on this. What resources are you providing? How are you providing them? When and how do you call `requestScan()`. What are you doing to determine it "isn't working".

Share some code.

I can't read your mind.

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 15, 2025, 4:39am UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/9 "2025-10-15T04:39:39Z")

</div>

![Screenshot (28)](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/e/9e8c0dbe1bed642631da4f80dd79008e1ee6ab32.png)

I'm adding these **custom fonts** and **themes** to Ignition 8.3 programmatically using Java code — copying them into the folders under  
`data/config/resources/core/com.inductiveautomation.perspective/`.

After installing the module and performing the initial required restart, the new fonts and themes do **not** appear automatically.  
I have to either **restart the Gateway again** or **run “Scan File System”** manually for them to be detected.

I also tried calling the following APIs after copying the files:

```python
context.getProjectManager().requestScan();
context.getConfigurationManager().requestScan();

```

But neither of them caused the fonts or themes to be recognized automatically.

---

<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:** [October 15, 2025, 11:15am UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/10 "2025-10-15T11:15:23Z")

</div>

You probably should be constructing resources instead of copying files. (And I would expect no rescan required.)

---

<div class="post-metadata">

**Author:** ![Sahil\_Bendale](https://avatars.discourse-cdn.com/v4/letter/s/977dab/32.png) [@Sahil\_Bendale](https://forum.inductiveautomation.com/u/Sahil_Bendale)\
**Post date:** [October 15, 2025, 12:27pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/11 "2025-10-15T12:27:20Z")

</div>

Try a test first, call the API to Get Themes Names to check whether your custom theme actually registered or not.

I ran into this issue where Ignition did not register the themes if I created the theme in the file system.

If you create the theme using the Create Themes API and then push the files for that theme using Update Themes Data File calls, it should work without having to rescan the file system or the configuration, you’ll just need to close the designer and launch it again to see the theme in effect.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 15, 2025, 1:17pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/12 "2025-10-15T13:17:37Z")

</div>

At what point in your module lifecycle do you copy the files and call `requestScan()`?

The "scan file system" routes use the same API.

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 15, 2025, 3:39pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/13 "2025-10-15T15:39:20Z")

</div>

I call `gatewayContext.getProjectManager().requestScan()` inside the `startup()` method of my `GatewayHook`, and file-copying code inside the `setup()` method.

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 15, 2025, 3:51pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/14 "2025-10-15T15:51:12Z")

</div>

Here’s what I’m trying to do programmatically:

1. Copy the `myTheme-dark` and `myTheme-light` folders.
2. If the `override-dark` and `override-light` folders **do not exist** , create them and copy the same files there.
3. If those folders **already exist** , open their `index.css` files and check if my custom `@import` lines are missing then append them.

Is it possible to perform these steps using the Ignition API instead of manually manipulating the filesystem?

---

<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:** [October 15, 2025, 4:13pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/15 "2025-10-15T16:13:34Z")

</div>

Yes, absolutely. Look at the API for `ConfigurationManager`, including methods from the parent class:

> **[ConfigurationManager](https://files.inductiveautomation.com/sdk/javadoc/ignition83/8.3.0/com/inductiveautomation/ignition/gateway/config/ConfigurationManager.html)**
>
> declaration: package: com.inductiveautomation.ignition.gateway.config, interface: ConfigurationManager

Take a look at this thread for an extremely similar task:

> [@Add a resource (icons svg lib) for the new API](https://forum.inductiveautomation.com/t/add-a-resource-icons-svg-lib-for-the-new-api/110976):
>
> I would like to add a resource (icons svg lib) for the new API. Resource will be added in C:\Program Files\Inductive Automation\Ignition\data\config\resources\core\com.inductiveautomation.perspective\icons\ pseudo code import com.inductiveautomation.ignition.common.resourcecollection.Resource import com.inductiveautomation.ignition.common.resourcecollection.ResourceBuilder res = ResourceBuilder().setType("icons").setPath("...testicons").setData(u"blabla").setLastModified(System.currentTimeM…

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 16, 2025, 8:47am UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/16 "2025-10-16T08:47:35Z")

</div>

In my module, I currently use the following two utility functions:

**1️⃣ Append a CSS import line if it doesn’t already exist:**

```python
private void appendToFile(String filePath, String lineToAppend) {
    try {
        List<String> lines = Files.readAllLines(Paths.get(filePath));
        if (!lines.contains(lineToAppend)) {
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
                writer.write(lineToAppend);
                writer.newLine();
            }
        } else {
            System.out.println("Line already exists in the file.");
        }
    } catch (IOException e) {
        System.out.println("IOException: " + e.getMessage());
    }
}

```

**2️⃣ Copy a directory (like theme folders) from inside the JAR to Ignition’s filesystem:**

```python
private void copyDirectoryFromJar(String sourceDir, File destDir) {
    try {
        URL resourceURL = getClass().getResource(sourceDir);
        if (resourceURL != null) {
            log.error("resourceURL = " + resourceURL);
        }

        if (resourceURL == null) {
            log.error("Resource not found: " + sourceDir);
            return;
        }

        if (resourceURL.getProtocol().equals("jar")) {
            String string = getJarPath(resourceURL);
            try (JarFile jar = new JarFile(string)) {
                Enumeration<JarEntry> entries = jar.entries();
                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    if (entry.getName().startsWith(sourceDir.substring(1))) {
                        String fileName = entry.getName().substring(sourceDir.length() - 1);
                        File targetFile = new File(destDir, fileName);
                        if (entry.isDirectory()) {
                            targetFile.mkdirs();
                        } else {
                            try (InputStream in = jar.getInputStream(entry);
                                 OutputStream out = new FileOutputStream(targetFile)) {
                                byte[] buffer = new byte[1024];
                                int bytesRead;
                                while ((bytesRead = in.read(buffer)) != -1) {
                                    out.write(buffer, 0, bytesRead);
                                }
                            }
                        }
                    }
                }
            }
        } else {
            log.error("Unsupported protocol: " + resourceURL.getProtocol());
        }
    } catch (IOException e) {
        throw new RuntimeException("Error copying resources from JAR", e);
    }
}

```

I use these two functions to automatically:

- copy my **theme folders and fonts** into Ignition’s Perspective resource directories, and
- append my custom CSS import lines into existing `index.css` files if they’re missing.

* * *

### ❓My question:

Now that Ignition 8.3 introduces the new **ConfigurationManager API** ,  
what is the proper or recommended way to perform these operations (copying, appending, or updating Perspective resources) using the **official API** , instead of manipulating the filesystem directly?

Also,  
is there any way to **programmatically trigger a file system scan** (for example, something like `requestScan()`),  
so that the Gateway detects newly copied or modified resource files immediately?

I’ve tested several `requestScan()` variants and similar methods mentioned in older posts,  
but none of them seem to work in 8.3.

Since every rebuild requires reinstalling the module and restarting the Gateway,  
I want to ensure I’m using the most correct and efficient approach to achieve this.

Any guidance or example code using the new API would be greatly appreciated.

Thanks!

---

<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:** [October 16, 2025, 5:54pm UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/17 "2025-10-16T17:54:05Z")

</div>

> [@Mehrdad\_Telli](#):
>
> using the **official API**

Yes. Pushing changes via the configuration manager API will take effect instantly, with no need to scan for changes.

> [@Mehrdad\_Telli](#):
>
> **programmatically trigger a file system scan** (for example, something like `requestScan()`

`requestScan` **is that API**. `requestScan` is literally what the button on the web interface calls. Which is what a couple people have told you already.  
There is a "configuration" manager, and a "project" manager. Both are `ResourceCollectionManager`s. The only one relevant to Perspective themes and icons in the configuration manager.

> [@Mehrdad\_Telli](#):
>
> but none of them seem to work in 8.3.

You are doing something wrong, then, either in where you are placing your files, how your files are constructed as resources, or something else. But it's all moot if you properly use the configuration manager API directly.

> [@Mehrdad\_Telli](#):
>
> Any guidance or example code using the new API would be greatly appreciated.

Did you try the forum thread I linked above, where there's literally code written out to do **exactly what you're trying to do** , except for icons instead of themes?

---

<div class="post-metadata">

**Author:** ![Mehrdad\_Telli](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mehrdad_telli/32/77763_2.png) [@Mehrdad\_Telli](https://forum.inductiveautomation.com/u/Mehrdad_Telli)\
**Post date:** [October 18, 2025, 4:55am UTC](https://forum.inductiveautomation.com/t/scan-file-system/111455/18 "2025-10-18T04:55:53Z")

</div>

Thanks @ [Kevin.Herron](https://forum.inductiveautomation.com/u/kevin.herron) and @ [paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith) for your help.

I realized that I made a mistake during my testing — I was running the `context.getConfigurationManager().requestScan();` code inside the `setup()` method instead of the `startup()` method.

After moving it to `startup()`, the code worked exactly as Kevin mentioned.

Also, the Java copy and append code I shared earlier works perfectly as well.

Marking Kevin’s post as the solution since his answer was correct, and Paul’s explanation helped me understand the root cause.

Appreciate both of you for the clear guidance!
