Hi all – VFX/animation tech guy here who’s a relative newbie to PS development. I’m trying to figure out how to access environment variables in the running Photoshop session using UXP: the equivalent of CEP’s $.getenv.
Here is what I’m trying to do:
- We open Photoshop from an in-house app launcher, which launches it in a subprocess.
- As it does so, the app launcher adds some environment variables to the subprocess.
- Upon loading, Photoshop opens a custom UXP plugin.
- This plugin leverages the environment variables to do some work.
I can get most of this working, all the way up to the env vars. The closest I’ve come to accessing them is through using dotenv (with systemvars=true), but the variables it returns are from a clean shell environment, and do not include the app launcher alterations.
Storing the information in a .env file or a temp file is a non-starter. Our security department will not allow us to write this information to disk.
Anyone have any recommendations?
I know you said no local .env files etc, but if it’s a JSON file in the plugin folder what’s the difference between that and installing the plugin in the first instance?
(I’m playing a little dumb here based on my own conversations with pearl clutching sysops )
The environment variable information is bespoke to each user and even each time they launch Photoshop – it’s access tokens and information about the user’s tasks (which is determined inside the app launcher, then leveraged by the UXP plugin to communicate with various servers). It wouldn’t be feasible to hardcode that into a .env or JSON file that gets distributed with the plugin.
The only workaround I can think of right now is to have the app launcher dump the credentials in a temporary file, then have the UXP plugin read and delete it as soon as it starts up. This is likely to give our security folks conniptions, though – I’d much rather use environment variables, if possible.
Oof, super awkward.
Strikes me that you’re running out of options, if security is the concern is a centralised REST API an option?
I had to do that under CEP and with some authorisation it was acceptable to the nerds
Greetings from another VFX/Animation guy!
If you’re not worried about getting your hands dirty with writing some C++ you can write a little custom C++ add-on for your UXP plugin. This allows you to have full access to anything a random process would have access too. I’ve used this mechanism to allow my UXP plugin to run a subprocess (here’s a report on it). In your case the add-on would simply read environment variables (i.e. the equivalent of getenv).
It would definitely be nice if this existed in UXP as a feature. We could have a whitelist of specific variables in the manifest that a script would want to access (same way as allowing specific domains).
@Timothy_Bennett – Sadly, it’s a REST API to which we’re trying to get the user access, and for which we need the security tokens. :-/
@dotproduct - Thank you so much for the advice on this! That’s… a heavy duty way to go, but sounds like the only way forward for now. I will admit, as someone who’s never scripted for Adobe products before, I am flabbergasted that there’s no environment variable access to speak of.
Totally hear you. UXP was designed very heavily with security and sandboxing in mind and not necessarily tailored towards the needs of a VFX pipeline for instance. We haven’t had proper random file access until earlier this year, just as an example, and the C++ add-on route is currently the only way to run a subprocess as part of the UXP plugin, as another example. That said Adobe has been very accommodating of feature requests. So this might be one of them.
In terms of the C++ add-on, without having thought this through in detail, it appears like this could be as simple as just calling std::getenv() and then the rest is just boilerplate setup code.
@jasonporath Welcome to Ps extensibility from a former VFX/animation TD.
The hybrid plugin is a probably the best workaround until env variables are exposed in UXP environments. I know I wouldn’t be excited about doing that especially for a cross-platform studio, but I should think that minimal alterations to the example plugin would be sufficient.
Thanks for the feedback, @dotproduct and @samgannaway! For the time being, I’ve opted to stick with CEP, for two reasons:
- Keeping velocity (we already have a working CEP version)
- Keyboard shortcuts (UXP scripts in PS seemingly can’t have keyboard shortcuts associated with them, at least yet?)
I’ll definitely be switching over to UXP at some point, but we’ll be iterating and working out the core workflow in CEP first.
Sounds like a prudent decision (provided you don’t have ARM support planned).
I am curious about the keyboard shortcut comment. Would you tell me more about that?
@samgannaway - sadly, we are gonna have to support M-series macs, and thus loading everything in Rosetta mode. Feels janky but for now it’s necessary.
The keyboard shortcut – we want an easy way for a user to quickly go through a workflow that’s in the panel (think “get prompted to give a note and then publish the working file”). To that end, we want them to be able to do so with keyboard shortcuts. With CEP, we’ve been able to do small one-off scripts that toss CSXSEvents and do the relevant business logic – those get added to the menus in such a way that they can have keyboard shortcuts associated with them.
With UXP, when we specify one-off scripts in the manifest, that show up in the menus, I do not seem to be able to associate keyboard shortcuts with them.
I hope that makes sense, I’m still not very fluent with the Adobe lingo.
Rosetta may well suffice until we get env access in UXP.
If I’m understanding your description, you have some .jsx scripts that you place in Scripts directory thus making them available for keyboard shortcuts. Those scripts fire events that trigger functions in the CEP extension.
You are correct in that the menu items in the UXP plugin’s submenu (under Plugins), should also appear for keyboard shortcut assignment. I have inquired about it. It will likely be either a simple fix or bit of a bear.
It seems to me that we should still be able to send a message or event from a script to a UXP plugin, even if it is ExtendScript. Although that might be easier in UXP Scripting. An ugly workaround would be to use the new
recordAction to record those function calls to Actions. Actions can have an F-key assignment.
Yep, that’s an accurate assessment of what I was trying to get across! Thanks, and sorry, I’m still finding my footing in speaking to the myriad scripting contexts.
I’d be curious to know how one could send events from a jsx ExtendScript to a UXP plugin. I’d poked around to see if there was an equivalent workflow to the CSXSEvent one, but I couldn’t figure anything out. I’d figured I’d try and do socket communication if it came to it, but since we’re sticking with CEP for now, maybe it won’t be necessary by the time we port to UXP.