State of arbitrary file access and shell command support

Happy new year Adobe! I was wondering if there has been any development in supporting arbitrary file access or running shell commands/subprocesses for enterprise use-cases? Both topics have been brought up and discussed in one way or the other in the past (notably: Run extendscript from uxp). I’d love to know what the status is, if there’s any plans for this year, etc. concerning:

  • Random file access: While sandboxing is an understandable requirement for market place plugins it can be quite an impediment in a (VFX/animation) studio context, where pipeline and automation is key. Having the ability to access files by path without user interaction seems like an important ingredient on the road to adopt UXP (at least in my experience so far). I know there are all sorts of work arounds floating around in the forum, but they remain work arounds and sometimes are impractical, especially if file locations aren not organized under a common root or known a priori. That said, with changes in the manifest permission system and the introduction of the fs module it really seems like we are so close. :sweat_smile: What appears to be missing is the bridge between fs and API functions requiring file/folder entry tokens. For example it’s not clear to me how to use app.open() with an arbitrary file path vs. entry (please advice if this has been addressed, I might have missed the corresponding docs).

  • Shell commands: Photoshop is a very important tool in our pipeline. However, for us it’s just one cook in a larger kitchen. To properly integrate it into our pipeline we would love the ability to run shell commands, e.g. in order to run helper apps or move exported Photoshop data to a next pipeline step. I’m aware that running shell scripts might seem somewhat archaic to the rest of the community, however they are a reality in VFX production, where we often can’t afford the time/budget to develop web services or proper app bundles. If there was a solution to support shell commands as a feature that can be enabled via special permission or as an enterprise-only feature that would be fantastic.

Personally I’m quite excited to get these issues out of the way and start adopting UXP, not to get parity with what we currently have implemented in extendScript but to get functionality beyond what was possible in the old world.

3 Likes

Hi there!

@Sujai and @justin2taylor can perhaps help out about the random file access progress.

@pkrishna Please note this shell command use case. Shell commands are used outside of the VFX world as well to do things like launch helper apps locally.

I’ve also seen the request to “call ExtendScript from UXP” elsewhere…

There is a better “shell” solution for UXP coming soon, I don’t believe I’m able to talk about it yet but will post here when I can.

And yes, random file access getting bridged to the application APIs is very important. I’ve brought this up a few times, thank you for also bringing it up.

Good morning! Just wanted to follow up on my own thread. The first topic, that I had brought up, Random File Access, is resolved with release 24.2 (February 2023) and the introduction of the fs module as well as getEntryWithUrl (getEntryWithUrl). I tested this in our pipeline and was able to access both files locally on our Macs as well as network drives (NFS). This is huge! Thanks Adobe for adding these features!!

To enable random file access without ad-hoc user permissions a corresponding setting is necessary in your manifest:

"requiredPermissions": {
    "localFileSystem": "fullAccess"
  }

Here’s an example snippet to get an entry to use with the Photoshop API’s functions relying on tokens (such as app.open()):

const lfs = require("uxp").storage.localFileSystem;
const fileEntry = await lfs.getEntryWithUrl("file:/YOUR_FILE_PATH}");

If you want to read your own files, e.g. configs, text files, etc. (not through Photoshop API functions) you can use the fs module, here are the docs: fs module. Here’s an example snippet to read an ASCII file:

const fs = require("fs");
const data = await fs.readFile("file:/YOUR_FILE_PATH}", options={encoding: "utf-8"});

Note: In case you’re using webpack you have to add fs to your config (as explained here), like:

externals: {
    ...
    fs: 'commonjs2 fs',
    ...
  },

I’m gonna follow up on this thread again once we have updates concerning shell commands. In the meantime I’m gonna mark this as resolved, so that if people come across this thread they get some useful info out of it.

5 Likes

Howdy! I wanted to follow up on this. I was wondering if there was any news concerning shell command support? I couldn’t find any reference to this or a similar feature in the recent blog post about UXP 2023 features. @justin2taylor, you had mentioned that there was something in the making, is that still the case? Thanks so much in advance for any updates!

Yes, I can talk about it now. UXP Hybrid Plugins are here! Basically you can do anything a native app can do now with custom hybrid native modules. For example you could write an execSync() equivalent in C++ and do all the same stuff you could with Node.js execSync()

https://blog.developer.adobe.com/announcing-uxp-hybrid-plugins-in-photoshop-beta-v24-0-9de650b53e17

2 Likes

First of all thanks @justin2taylor for the pointer. And thank you Adobe for UXP Hybrid Plugins!! They certainly give us the flexibility to solve this on our end. With the help of the SDK’s readme and example plugin it’s fairly straight forward to get started, provided you’re familiar with C/C++. It took me about a day to implement a basic execSync() (like @justin2taylor had suggested) and bundle it all up. For people who are not comfortable with getting their hands dirty in some C/C++ it might not be suitable, but on the flip side you get a lot of flexibility and the freedom to do stuff that may not be possible just through Javascript. However: I would say, with great freedom comes great responsibility. You can certainly do a lot but also break a lot (and I don’t mean that in a malicious sense), don’t attempt this if you don’t know C/C++! For folks who may want to try UXP Hybrid Plugins as well, here are a few things I found on the way:

  • The SDK’s example plugin uses a ‘main.js’ as entrypoint. I found it straight forward to just use my existing ‘index.js’ that gets built out of various modules, using npm/webpack, etc.
  • If you’re using webpack, don’t forget to add your add-on under ‘externals’ in the webpack config. Like so:
externals: {
    photoshop: 'commonjs2 photoshop',
    uxp: 'commonjs2 uxp',
    ...
    'YOUR_ADDON_NAME.uxpaddon': 'commonjs2 YOUR_ADDON_NAME.uxpaddon'
    ...
  }
  • Don’t forget to add the required entry for add-ons to the permissions section in the manifest. In fact the manifest needs a few changes, including listing the add-on. Read the SDK’s readme carefully, it goes over the different things you need to add.

Hello :slight_smile:

Any chance of a simpler solution to start a shell command? Otherwise, we will have to get our hands dirty in some C/C++ as this issue is blocking our studio’s python pipeline, but @dotproduct disclaimer scares us since we are just Python devs :smiley: .

1 Like

Same question as @Munshine . I used to be able to run sys commands to kick off secondary post-export processes from other programs in javascript. I don’t know or care to learn C++ and create a project that I have to build binaries just to launch a 1 or 2 line prompt.

A ready-to-use solution with Hybrid Plugins has been provided here: