• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
1

Looking for help with a windows compatible web socket workaround.

Community Expert ,
May 04, 2020 May 04, 2020

Copy link to clipboard

Copied

Hey there folks. It's another day, which means it's time to work together to find another workaround in order to obtain some basic functionality! If you're already convinced and you want in, head on over to the github page, then come back here and read the rest of this so you know what the goal is, silly goose.

 

In our art production workflow, it's important for my scripts to have access to the most up to date data (i have 2 main scripts, one that builds a mockup file based on JSON data from a web based app, and another that builds a production file including all roster data). Despite our policy that "no changes can be made after the order is approved", last minute roster/size changes are as predictable as tomorrow's sunrise. So, in order to ensure I'm getting the most up to date data, I get that data at runtime via a unique web link that includes the order number or design number.

 

Unfortunately, since Extendscript has no socket object, getting access to the internet isn't super straightforward. I've devised a bit of a hacky workaround on mac which dynamically writes an applescript .scpt file which contains instructions to execute a shell script which executes a curl command and saves the result to a local data file which can be read and validated in extendscript. This process has worked well for me for about a year now.... while all the artists were in the office and using iMacs... Now, with our new work from home reality, I need to adapt this functionality to work in a cross platform manner. However, I'm terribly terribly allergic to using Windows... Whenever I try to use it, i experience headaches, frustration, confusion, and rage. (EpiPens don't seem to help either.. doctors are baffled)

 

So, that's where you come in... Do you have experience in VBScript? Do you have more time than tasks to accomplish? Do you have a desire to contribute to a bit of open source software that could potentially be useful to dozens or hundreds of 3rd party developers who don't have access to a socket? Do you have the skills necessary to click on a github link and fork the project???

 

Any help you wish to give will be repaid handsomely in praise, appreciation, and respect. (I'm not sure how favorably these things convert into your own local currency, but I'd say it's worth it.)

TOPICS
Scripting , SDK

Views

2.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Valorous Hero , May 04, 2020 May 04, 2020

It's actually easier on Windows than may seem at first.

 

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim urlString, urlObj, jsxArgumentsArray
urlString = "http://www.some-website.com"
jsxArgumentsArray = Array()

Dim http
Set http = createObject("Microsoft.XMLHTTP")
Dim responseTextString

http.open "GET", urlString, false
http.send

If http.Status = 200 Then
	responseTextString = http.responseText
Else
	responseTextString = "ERRCODE : " & http.status
End If
ReDim Preserve jsx
...

Votes

Translate

Translate
Adobe
Valorous Hero ,
May 04, 2020 May 04, 2020

Copy link to clipboard

Copied

It's actually easier on Windows than may seem at first.

 

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim urlString, urlObj, jsxArgumentsArray
urlString = "http://www.some-website.com"
jsxArgumentsArray = Array()

Dim http
Set http = createObject("Microsoft.XMLHTTP")
Dim responseTextString

http.open "GET", urlString, false
http.send

If http.Status = 200 Then
	responseTextString = http.responseText
Else
	responseTextString = "ERRCODE : " & http.status
End If
ReDim Preserve jsxArgumentsArray(UBound(jsxArgumentsArray) + 1)
jsxArgumentsArray(UBound(jsxArgumentsArray)) = http.responseText

Set AdobeApp = CreateObject("Illustrator.Application")
jsxExecutableScriptPath = "C:\Folders\TheScript.jsx"
If (fso.FileExists(jsxExecutableScriptPath)) Then
	Set jsxExecutableScriptFile = fso.GetFile(jsxExecutableScriptPath)
	AdobeApp.DoJavaScriptFile jsxExecutableScriptFile.Path, finalizedArray
Else
	MsgBox "The Illustrator javascript file was not found at '" & jsxExecutableScriptPath & "'"
End If

 

It's easy if you are actually starting inside VBS because it's a quick one-way trip to JSX, with arguments.

But if you are starting out in JSX, then I am not quite sure about how to pass in arguments to VBS other than writing a temp text file. However, this has been working out for me well and I've got at least one client who uses this technique daily. There are some issues as to making sure IT gives your VBS file permissions for certain users so that it won't be stopped by the 'unverified publisher' type of alert message.

 

The other way to bypass needing VBS and AppleScript to do your web-calling is to simply use the way more involved CEP extension along with your scripting. With some studying and practicing, you can make a CEP extension that can be a global one which takes events from any of your JSX scripts and makes the http request, then runs your JSX script again but with new arguments that run the entire script, except now you'd have a statement which first checks for the arguments and then picks up where it left off when it last made its call to the CEP panel.

This may sound really wacky but it would totally work cross-platform.

 

Also, if using VBS you may want to actually pass in JSON as the arguments inside your temp text file. Of course the easiest is to use no JSON but some kind of string-splitting, but for JSON you'll have to find some piece of code that does JSON parsing in VBS. In my case, I found a script class which is way long but it's got these comments at the top should you ever wanna look for it.

 

Class VbsJson
		'Author: Demon
		'Date: 2012/5/3
		'Website: http://demon.tw

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 05, 2020 May 05, 2020

Copy link to clipboard

Copied

thanks Vasily, you pretty much covered it waaaaay better than I would have. Thanks for sharing.

 

for sake of completion, if you start with JSX, you would write a BAT file on the fly to run the http request VBS script you just posted.

so, jsx passes arguments to bat file. Bat file passes arguments to vbs script.

 

this is the BAT sample file I'm writing from jsx. The bat command takes the name of the program you want to run, and as many arguments you need separated by a space. First argument is the VBS you want to run. The next 2 arguments are the script arguments. I'm passing my name and the url we need to query

cscript.exe "C:\Users\canto\Google Drive\Adobe Scripts\socket_xhttpRequest.vbs" "carlos" "https://reqbin.com/echo/get/json"

 

then still in jsx, we run the bat file we just wrote

File ("~/full path/myBatFileToRunVBS.bat").execute();

 

and finally, here's your VBS file. I just added a couple of lines to process the arguments passed by the BAT file.

this vbs script can also run with no arguments, double clicking on it will run with default url

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim urlString, urlObj, jsxArgumentsArray

if WScript.arguments.count>0 then
    msgBox "Argument 0: " & WScript.arguments(0)
    msgBox "Argument 1: " & WScript.arguments(1)

    urlString = WScript.arguments(1)
else
    urlString = "https://reqbin.com/echo/get/xml"
end if

jsxArgumentsArray = Array()

Dim http
Set http = createObject("Microsoft.XMLHTTP")
Dim responseTextString

http.open "GET", urlString, false
http.send

If http.Status = 200 Then
	responseTextString = http.responseText
Else
	responseTextString = "ERRCODE : " & http.status
End If

msgbox responseTextString

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
May 08, 2020 May 08, 2020

Copy link to clipboard

Copied

Yea way to go with the bat file - I actually never used those before.

Also I fixed a typo in my snippet example, the urlObj("url") was the remnants of using that JSON parser VBS code which took the JSON written down by my JSX. I figured the simpler example is to use a regular string.

So, what's cscript.exe ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 09, 2020 May 09, 2020

Copy link to clipboard

Copied

cscript is the program that runs vbs script in command line, as oposed to wscript which is the program that usually runs a script when you double click on it.

 

I did notice the url object reference. So where is @williamadownling?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 15, 2020 May 15, 2020

Copy link to clipboard

Copied

heeeeyyyyyy. i'm back. Sorry gentlemen. I happened to post that question right before it was time to prepare for my intermediate algebra final and suddenly i had no time for anything..

 

But I'm back now. 😃

 

This all looks great. Seems to be pretty much exactly how i've been doing it on mac. So just to make sure I have the workflow down, it'll go like this:

Execute main_script.jsx in Illustrator

write dynamic bat file (with runtime data, like order number) from jsx (I can just change those arguments to whatever, right? and then access them by index with WScript.arguments(0)?)

execute bat file from jsx

capture http response (this is where i'll still need help.. I'm guessing that "msgbox" is the VBS equivalent of alert()? How can i return the information out of the vbs script and back into the original jsx, since that's where it will be handled.)

proceed with main_script.jsx

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
May 15, 2020 May 15, 2020

Copy link to clipboard

Copied

At the end of my snippet there's an example of the Illustrator VBScript method called DoJavaScriptFile, it lets you run a javascript and pass in the arguments. However you will have to ensure your jsx script can be called in multiple ways, one of which would make it sensitive to such an argument. When you run it first without the argument, it will run to the point of doing the VBScript. Then, the VBScript will trigger the same script that can use a bunch of shared functions with the part that was before VBS, and this time it will read the arguments and continue at the next part you want to run after it has gotten those arguments. Or you can have two different scripts too, in case your web stuff fetches some data and populates a crazy UI, but you want the other half to be separate from the UI code-wise and triggerable by yet other scripts that may not have a UI but be part of a whole other pipeline.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 15, 2020 May 15, 2020

Copy link to clipboard

Copied

the steps you described are correct. Once you get the data from the web, you just parse it and pass it as arguments to your (2nd) jsx. 

 

but it depends on what you decide, as Vasily mentioned, you can start with VBS, fetch data, run jsx. Or you start with jsx, BAT, vbs, fetch, jsx.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 18, 2020 May 18, 2020

Copy link to clipboard

Copied

Hmmm. I don't really have a "2nd" jsx. Here's my workflow:

 

  • run main_script.jsx
  • gather data about the active document (looking for order numbers or design numbers, validating the document, etc)
  • main_script.jsx calls a getData("http:\\website.com","1234567") function and passes in a URL and some info for the resource string.
    • getData() function checks the OS and decides whether to use applescript or vbs.
    • using the appropriate method, the data is retrieved from the URL
    • return the retreived data back to jsx (as a string is fine)
    • parse the data (i can do this in the jsx. no need for parsing or validating data in vbs or applescript, thank Spaghetti Monster).
    • return the parsed data, or undefined.
  • if data returned, process and complete the task.
  • else log, alert, and (depending on the situation, exit or continue)

 

How can i achieve the step higlighted in pink? In my Mac version, I use BASH to print the results of the curl command to a local file. then the jsx opens/reads that file and parses the data. Can the vbs do the same?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
May 19, 2020 May 19, 2020

Copy link to clipboard

Copied

According to your mac code, you are using loops with a $.sleep delay, which you could also use in this case since it is looking at whether a file was written down. And that's what the VBS file will need to do as well, which you can do with this kind of code https://stackoverflow.com/questions/11503174/how-to-create-and-write-to-a-txt-file-using-vba

 

Dim strPath as String
strPath = "C:\Myfolders\theFile.txt"
Dim fso as Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim oFile as Object
Set oFile = FSO.CreateTextFile(strPath)
oFile.WriteLine "test" 
oFile.Close
Set fso = Nothing
Set oFile = Nothing

 

 It looks like this delay timeout approach worked for you for a long time, so unless Windows acts differently regarding sleeps in jsx, which it shouldn't of course, then it would be super easy to plug in a little vbs into the workflow. I think I can help put a little snippet on your github and it will help me practice what a pull request is and stuff.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 19, 2020 May 19, 2020

Copy link to clipboard

Copied

LATEST

Thanks V. I did find an example of writing a file with vbs and i started to implement it yesterday. unfortunately my wife's car broke down while she was in a drivethru getting lunch.. so i had to run down and solve that problem which then led me to replacing an alternator last night. I'm going to try and implement this anyway (though, it appears sublime text doesn't even have syntax highlighting for vbs... so it's tricky to read. lol), but if you wanted some github practice with forking, pull requests etc.. by all means, feel free. 

 

Thanks a ton guys.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines