Unable to open files from the local directory, using getEntryWithUrl() and getEntries() is this where i am going wrong?

I am trying to access the directory of the current active document, search that directory for images which share the first 9 digits of the active documents name, then open those matching files.

Is this possible?

I am searching on the local filesystem not in the pre-made plugin folders.

The below code works up until it reaches the try/catch

This is my code:

const fsProvider = require('uxp').storage.localFileSystem;
const app = require('photoshop').app
const activeDocumentPath = app.activeDocument.path;
const result = activeDocumentPath.replace(/\/[^/]*$/, "");
// Find Retouch Notes Folder Function 
async function findFolder(path) {
    // Access other location
    if (fsProvider.isFileSystemProvider) {
      try {
        const pluginFolder = await fsProvider.getEntryWithUrl(path);     
        const folderArray = await pluginFolder.getEntries();
        const name = app.activeDocument.name.split("").slice(0,9).join("")
        for(const obj of folderArray){
          if(name == obj.name.split("").slice(0,9).join("")){
            console.log(`${obj.name} is a match!`);
            console.log(`${path}/${obj.name}`)

            // Now I have the files path, how do I open a file in photoshop? 
            try{
              const fd = await app.open(`${path}/${obj.name}`);
            } catch (error){
              console.log(error)
            }
          }
        };
      } catch (e) {
        console.error(e);
      }
    }
}
findFolder(result)

This is the error that’s returned:

Error: Parameter must be a valid entry representing a file or a folder\
    at Object._getEntryDataToNative (uxp://uxp-internal/webfs_scripts.js:2)\
    at Object.createSessionToken (uxp://uxp-internal/webfs_scripts.js:2)\
    at Object.createSessionToken (uxp://uxp-internal/webfs_scripts.js:2)\
    at Object.createSessionToken (uxp://uxp-internal/webfs_scripts.js:2)\
    at Photoshop.open (uxp://uxp-internal/ps-app.js:1)\
    at findFolder (VM12 main.js:45)

if you just hope to open image on Photoshop, giving entry object in app.open method.
and place any Photoshop method in executeAsModa scope.
I confirm it works on my environment and not to forget manifest declaring “requiredPermissions” {“localFileSystem”: “fullAccess”}
and also I suggest avoid using variable “path”.
because on UXP. global object has path class which has many file path methods like Node.js path module.

const fsProvider = require('uxp').storage.localFileSystem;
const app = require('photoshop').app;
const core = require('photoshop').core;
const fs = require("fs");
const activeDocumentPath = app.activeDocument.path;

const result = path.dirname(activeDocumentPath);

// open image on photoshop from inside of executeAsModal
const openImage = (entryPath) => {
  return new Promise((resolve,reject) => {
      core.executeAsModal(async () => {
          // Now I have the files path, how do I open a file in photoshop? 
          try{
            console.log(entryPath);
            const fd = await app.open(entryPath);
            resolve(fd);
          } catch (error){
            console.log(error);
            reject(error);
          }
      },{commandName: "open image"});
  })
}

// Find Retouch Notes Folder Function 
async function findFolder(filePath) {
    // on UXP global object has path class. I recommend avoid use "path" variable

    // Access other location
    if (fsProvider.isFileSystemProvider) {
      try {
        const r = fs.lstatSync(filePath);
        console.log(r.isDirectory());
        const pluginFolder = await fsProvider.getEntryWithUrl(filePath);     
        const folderArray = await pluginFolder.getEntries();
        const name = app.activeDocument.name.split("").slice(0,9).join("");
        for(const obj of folderArray){
          if(name == obj.name.split("").slice(0,9).join("")){
            console.log(`${obj.name} is a match!`);
            console.log(path.join(filePath, obj.name));
            //turn path into entry object
            const entryPath = await fsProvider.getEntryWithUrl(path.join(filePath, obj.name));
            await openImage(entryPath);
          }
        };
        //you can open some other image
        await openImage(await fsProvider.getEntryWithUrl(path.join(filePath, "yourimage.psd")));
      } catch (e) {
        console.error(e);
      }
    }
}


document.getElementById("btnPopulate").addEventListener("click", async() => await findFolder(result));
1 Like

Thank you for the reply, I really apperciate it.

Are you using the react-starter? I’m running mine on the quick-layer-starter and after a quick copy and paste of your code into my template it returns a:

Error: Unimplemented method: lstatSync

I’ll have some more time tonight to delve into the issue but just wanted to thank you and also check the template that you were using.

Cheers

I wrote it on Vanilla JS I didn’t use any template but I think you are missing declaration full access on manifest .
please check your manifest.json.

“localFileSystem”: “fullAccess”

{
    "id": "com.adobe.example.vanilla-ps-js",
    "name": "Starter Panel",
    "version": "1.0.0",
    "main": "index.html",
    "host": {
        "app": "PS",
        "minVersion": "24.0.0",
        "data": {
            "apiVersion": 2
        }
    },
// you need to give permission of file access here
    "requiredPermissions": {
        "localFileSystem": "fullAccess"
    },
    "manifestVersion": 5,
    "entrypoints": [
        {
            "type": "command",
            "id": "showAlert",
            "label": "Show alert"
        },
        {
            "type": "panel",
            "id": "vanilla",
            "minimumSize": {"width": 230, "height": 200},
            "maximumSize": {"width": 2000, "height": 2000},
            "preferredDockedSize": {"width": 230, "height": 300},
            "preferredFloatingSize": {"width": 230, "height": 300},
            "icons": [
                { "width": 32, "height": 32, "path": "icons/icon_D.png", "scale": [ 1, 2 ], "theme": [ "dark", "darkest" ], "species": [ "generic" ] },
                { "width": 32, "height": 32, "path": "icons/icon_N.png", "scale": [ 1, 2 ], "theme": [ "lightest", "light" ], "species": [ "generic" ] }
            ],
            "label": {"default": "Starter Panel"}
        }
    ],
    "icons": [
        {
            "width": 23, "height": 23, "path": "icons/dark.png", "scale": [ 1, 2 ],
            "theme": [ "darkest", "dark", "medium" ]
        }, {
            "width": 23, "height": 23, "path": "icons/light.png", "scale": [ 1, 2 ],
            "theme": [ "lightest", "light" ]
        }
    ]
}

I saw same error without permission.
lstatSync just inspects whether filePath is directory or not. it’s not necessity but without permission , getEntries method, path, and fs module won’t work as well.

I got the same error. But I was using manifestVersion: 4 where permissions do not exist. It also seemed very random. Sometime it worked and sometime it did not. I could not find a pattern.

I changed manifest to version 5 and added permissions and then it worked without flaw.

1 Like