Copy link to clipboard
Copied
Hi,
I'm currently writing an automation plugin which should execute some javascript. In general it works, but I get some weird behaviour when executing certain javascript functions:
If I try to execute:
app.open(File("C:/Path/To/File.bmp"));
It will return the following error:
Error 8000: Cannot open the file because the open options are incorrect\rLine: 1\r-> app.open(File("C:/temp/bla_2.1000.bmp"));'
If I execute the exact same command from inside AdobeExtendToolkit it works as it should and just opens the image.
My first guess was, that it doesn't work, because I create the JSEngine in a different thread, but even if I run my evaluation method in the main thread the result is the same.
Now I think, that it doesn't sources some dependencies by default and I have to source them manually, but maybe I'm totally off the topic with this assumption.
I would be really grateful for any hint on this. Thanks,
Martin
Here is an exerpt of my code (its mostly based from this threadRe: Call Script through plug-in.😞
std::string AutomationPlugin::evaluateCommand(std::string command)
{
this->inProgress = true;
std::string answer = "";
const char * jscode = command.c_str();
ASErr err = 0;
JSScriptingSuite2 * sScriptingSuite = NULL;
/* get a new javascript engine */
err = this->basicSuite->AcquireSuite( kJSScriptingSuite, kJSScriptingSuiteVersion2, (const void**)&sScriptingSuite);
if (sScriptingSuite == NULL) //Also support Photoshop CS1-CS4 and Elements 6-10
{
err = this->basicSuite->AcquireSuite( kJSScriptingSuite, kJSScriptingSuiteVersion1, (const void**)&sScriptingSuite);
}
if (sScriptingSuite == NULL)
{
this->inProgress = false;
this->reply = "Error: ScriptEgine was not available!";
return this->reply;
}
JSEngineRef engineRef = NULL;
err = sScriptingSuite->CreateEngine( &engineRef );
while (sScriptingSuite->ScriptIsRunning())
{
// .. wait until all other scripts are done ..
}
/* source some additional functions in external javascript files */
std::string scopeCmd = this->getScopeCommand();
std::wstring wideScopeCmd = this->strToWstr(scopeCmd);
const ASUnicode * scopeResult = NULL;
err = sScriptingSuite->ExecuteScript(engineRef, (ASUnicode *)wideScopeCmd.c_str(), kJSExecutionModeNoDebug, &scopeResult);
/* if engine was found without an error.. */
if ( err == kSPNoError )
{
//Convert ascii to unicode
this->log(1, command);
std::wstring wideCommand = this->strToWstr(command);
std::wstring wideAnswer;
const ASUnicode * result = NULL;
/* THIS IS WHERE THE ERROR HAPPENS */
err = sScriptingSuite->ExecuteScript(engineRef, (ASUnicode *)wideCommand.c_str(), kJSExecutionModeNoDebug, &result);
wideAnswer = (wchar_t*)result;
answer = this->wstrToStr(wideAnswer);
if ( err != kSPNoError )
{
this->inProgress = false;
this->reply = "ERROR: " + answer;
return this->reply;
}
}
else
{
this->inProgress = false;
this->reply = "ERROR: " + answer;
return this->reply;
}
if (engineRef)
{
sScriptingSuite->DeleteEngine( engineRef );
}
this->inProgress = false;
this->reply = answer;
return this->reply;
}
Copy link to clipboard
Copied
Hi again,
after some debugging I found out, that it is a threading issue. I found out, that if I trigger the kPSPhotoshopCaller/kPSDoIt caller-selector combination. The plugin gets loaded in the current thread instead of the main. But if trigger the same caller/selector combination from the javascript interface in the ExtendScript Toolkit it gets executed in the main thread and works.
That leads me to another question, how can I trigger the doIt function from another thread to be started in the main thread?
Any help would be appreciated!
Thanks.
Copy link to clipboard
Copied
How are you doing this " trigger the kPSPhotoshopCaller/kPSDoIt" you should be playing an action and letting Photoshop do the caller/selector workflow.
You need to be doing everything on the main thread. Photoshop is not thread save regarding plug-in execution.
Copy link to clipboard
Copied
I use the following hack to make Photoshop react to the kPSDoIt. As you mentioned I can't play an action in the second thread, as this will fail, because Photoshop isn't thread safe with API-commands. What worked for me is making my plugin scriptable, then opening a jsScriptEngine in the second thread and trigger the action via the scriptingEngine. Using this workaround Photoshop will call the doIt callback of my plugin in main thread. Luckly that seems to works without a problem.. It's not nice, but it does the job.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more