Skip to main content
Participant
January 28, 2010
Answered

Send Key Strokes to CS3 document

  • January 28, 2010
  • 2 replies
  • 1504 views

Hi Everybody.

I'd like to know if it's possible via JS scripting to send a sequence of Key Strokes to an already open document.

Example:

I have an open document in PS CS3, then I'd like to go menu File/sequence commands/Browse and then load a JS script that sends a sequence of key strokes as same as if the user were typing it.

My purpose is to take access via keystrokes to some menus which aren't recorded neither by the action pannel recorder nor the scriptlistenerJS

Thanks in advance.

This topic has been closed for replies.
Correct answer Michael_L_Hale

Hi Michael L Hale,

Sorry for asking so much, but don't understand very well how to implement your example (I'm a beginner with photoshop scripting). Would it bother you to post a specific example of your function? I'd appreciate it so much.


Let's say that the csv file is always on the desktop( you could use a different folder ). With the doc with the datasets that need updating open run the script below. It does the same thing as File-Import-Variable Data Sets except that it sets the csv file without the dialog. You can even use it as part of your action.

 


BTW, if you import from the Image-Variables dialog's flyout menu scriptlistener doesn't output anything. You have to use File-Import-Variable Data Sets. That will get you to the same dialog and scriptlistener output.

 

var myCSVFile = new File('~/Desktop/myCSVFile.csv');
fileImportDataSets( myCSVFile );
// Imports a csv file using the first field as the dataset name
// the first field should be unique as it will be used to index the datasets for
// loopDataSets and applyDataSets functions
function fileImportDataSets( file ) {
    var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putClass( stringIDToTypeID( "dataSetClass" ) );
    desc.putReference( charIDToTypeID( "null" ), ref );
    desc.putPath( charIDToTypeID( "Usng" ), new File( file ) );
    desc.putEnumerated( charIDToTypeID( "Encd" ),
                                        stringIDToTypeID( "dataSetEncoding" ),
                                        stringIDToTypeID( "dataSetEncodingAuto" ) );
    desc.putBoolean( stringIDToTypeID( "eraseAll" ), true );
    desc.putBoolean( stringIDToTypeID( "useFirstColumn" ), true );
executeAction( stringIDToTypeID( "importDataSets" ), desc, DialogModes.NO );
}

2 replies

Inspiring
January 28, 2010

This would be possible on mac os with applescript. (but its ugly)

May be possible with visual basic on pc (I know ≤ 0 about pc's so someone could answer that).

I've not seen anything like this done with javascript. (but I've a lot to learn yet a maybe?)

Inspiring
January 28, 2010

Untested but possible alternative using bridge system();

"osascript -e 'tell application "System Events" to keystroke "N" using command down'"

Paul, if you write applescript text to file you can compile the script with shell 'osacomplie' but then you most likely know this already…

Paul Riggott
Inspiring
January 28, 2010

Thanks Mark, I didn't know that, will try to remember that. I only turn the Macs on to test any scripts otherwise I leave them alone!

Paul Riggott
Inspiring
January 28, 2010

I don't think you can do it from JavaScript.

What I do is use .Net for windows and AppleScript for the mac

Examples:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SendKeysTest
{
public class Driver
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("User32")]
public static extern int SetForegroundWindow(IntPtr hwnd);

public static void Main(string[] args) {
IntPtr iHandle = FindWindow("Photoshop",null);

SetForegroundWindow(iHandle);
SendKeys.SendWait("+]");
}
}
}


tell application "Adobe Photoshop CS3"
activate
tell application "System Events" to keystroke"["
end tell


Both methods need to be complied, the AppleScript as an app then run via JS using the File.execute(); command

Barleby_Author
Participant
January 28, 2010

Maybe there's an easier way to achieve what I want.

I'll explain the exact problem:

I have dozens of banners with common layers that I have to update very often (texts, background images...)

So I created a CSV file with the source data that every banner reads via (data set, variables... in the Image menu). I successfully made everything but found an issue that might be a CS3 bug:

     Everytime I update myDataFile.csv  with new data, the document in photoshop doesn't update data when pressing Image/Apply set of data as Photshop seems to cache the former data of the file. The only way I found to solve this is "force" PS to read the file again: enter the Images/Set of Data Import option, select the same CSV file and then Apply. Then it takes the right values. This is OK for one document, but when I Record an action/script that enters the mentioned menu,nothing is registered, that's the reason of sending keystrokes from script to open and select desired options in a particular menu.

Inspiring
January 28, 2010

Barleby_ wrote:

Maybe there's an easier way to achieve what I want.

There is. Here is a function that inports a csv file.

// Imports a csv file using the first field as the dataset name
// the first field should be unique as it will be used to index the datasets for
// loopDataSets and applyDataSets functions
fileImportDataSets = function( file ) {
    var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putClass( stringIDToTypeID( "dataSetClass" ) );
    desc.putReference( charIDToTypeID( "null" ), ref );
    desc.putPath( charIDToTypeID( "Usng" ), new File( file ) );
    desc.putEnumerated( charIDToTypeID( "Encd" ),
                                        stringIDToTypeID( "dataSetEncoding" ),
                                        stringIDToTypeID( "dataSetEncodingAuto" ) );
    desc.putBoolean( stringIDToTypeID( "eraseAll" ), true );
    desc.putBoolean( stringIDToTypeID( "useFirstColumn" ), true );
executeAction( stringIDToTypeID( "importDataSets" ), desc, DialogModes.NO );
}