Skip to main content
johny roger
Inspiring
March 31, 2017
Question

Getting the path of linked (smart) object / PS Bug?

  • March 31, 2017
  • 1 reply
  • 7627 views

Hello All

i'm trying to read the path of the linked object/layer trough script. The path information seems to be available in the Layers properties panel (see screenshot 1).

When i try to use the command "reveal in finder" from within Photoshop, i do get an Error "Could not complete your request because of a program error."

So, i'm not able to use Scriptlistener to use the code for that.

Does anyone have a working AM code for this function available and knows why i do get this error on my side (on all psd documents i tried).

alert(app.activeDocument.activeLayer.filePath);

EDIT:

found this code that checks if there is a linked smart object and returns it's path.

Unfortunately i can't get it working like:

//Pseudocode:

If (activeLayer = linkedSmartobject)

{

var activeDesignPath = activeLayer.filePath;

} else {

// ignore ALL errors and continue (next layer will then be checked)

};

// Export/save as jpg to the root Folder of the linked smart object.

app.activeDocument.saveAs((new File(activeDesignPath + "/_Files Export/with GTO Background" +'/' + activeColor + ' ' + basename + ' ' + designDoc.activeLayer.name +'.jpg')),jpegOptions,true);

Original Script:

  1.   if (app.documents.length)   
  2.   {   
  3.     var doc = app.activeDocument;   
  4.     for (var ilayer = 0; ilayer < doc.artLayers.length; ilayer++)   
  5.     {   
  6.       var layer = doc.artLayers[ilayer];   
  7.       if (layer.kind == LayerKind.SMARTOBJECT)   
  8.       {   
  9.  
  10.         var ref = new ActionReference(); 
  11.         ref.putIdentifier(charIDToTypeID('Lyr '), layer.id ); 
  12.      
  13.         var desc = executeActionGet(ref); 
  14.         var smObj = desc.getObjectValue(stringIDToTypeID('smartObject')); 
  15.         var localFilePath = smObj.getPath(stringIDToTypeID('link'));   
  16.       }   
  17.     } 
  18.   }  
This topic has been closed for replies.

1 reply

JJMack
Community Expert
Community Expert
March 31, 2017

The code you found works for linked smart object layers it will through an error if the object is not a linked file. You can use a try catch to note the and ignore none linked smart object layers.

function processSmartObj(obj) {

  var localFilePath = "";

  var ref = new ActionReference();  

    ref.putIdentifier(charIDToTypeID('Lyr '), obj.id );  

    var desc = executeActionGet(ref);  

    var smObj = desc.getObjectValue(stringIDToTypeID('smartObject'));  

  try {

  var localFilePath = smObj.getPath(stringIDToTypeID('link')); 

  alert("Layer " + obj.name + ' linked file is"' +  localFilePath + '"');

  }

  catch(e) {}

  return localFilePath;

}

You could put some boilerplate around the process to structure the code an make it  more readable  for example process all layer in a document may look something like this.

/* ==========================================================

// 2017  John J. McAssey (JJMack)

// ======================================================= */

// This script is supplied as is. It is provided as freeware.

// The author accepts no liability for any problems arising from its use.

// enable double-clicking from Mac Finder or Windows Explorer

#target photoshop // this command only works in Photoshop CS2 and higher

// bring application forward for double-click events

app.bringToFront();

// ensure at least one document open

if (!documents.length) alert('There are no documents open.', 'No Document');

else {

  // declare Global variables

  //main(); // at least one document exists proceed

    app.activeDocument.suspendHistory('Some Process Name','main()');

}

///////////////////////////////////////////////////////////////////////////////

//                            main function                                  //

///////////////////////////////////////////////////////////////////////////////

function main() {

  // declare local variables

  var orig_ruler_units = app.preferences.rulerUnits;

  var orig_type_units = app.preferences.typeUnits;

  var orig_display_dialogs = app.displayDialogs;

  app.preferences.rulerUnits = Units.PIXELS;   // Set the ruler units to PIXELS

  app.preferences.typeUnits = TypeUnits.POINTS;   // Set Type units to POINTS

  app.displayDialogs = DialogModes.NO;     // Set Dialogs off

  try { code(); }

  // display error message if something goes wrong

  catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }

  app.displayDialogs = orig_display_dialogs;   // Reset display dialogs

  app.preferences.typeUnits  = orig_type_units; // Reset ruler units to original settings

  app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings

}

///////////////////////////////////////////////////////////////////////////////

//                           main function end                               //

///////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////

// The real code is embedded into this function so that at any point it can return //

// to the main line function to let it restore users edit environment and end      //

/////////////////////////////////////////////////////////////////////////////////////

function code() {

  processArtLayers(activeDocument) 

}

function processArtLayers(obj) { 

    for( var i = obj.artLayers.length-1; 0 <= i; i--) {processLayers(obj.artLayers);} 

    for( var i = obj.layerSets.length-1; 0 <= i; i--) {processArtLayers(obj.layerSets); } // Process Layer Set Layers 

}

function processLayers(layer) {

  switch (layer.kind){

  case LayerKind.SMARTOBJECT : processSmartObj(layer); break;

  default : break; // none process layer types catch all

  }

}

//////////////////////////////////////////////////////////////////////////////////

// Layer Type Functions //

//////////////////////////////////////////////////////////////////////////////////

function processSmartObj(obj) {

  var localFilePath = "";

  var ref = new ActionReference();   

    ref.putIdentifier(charIDToTypeID('Lyr '), obj.id );   

    var desc = executeActionGet(ref);   

    var smObj = desc.getObjectValue(stringIDToTypeID('smartObject'));   

  try {

  var localFilePath = smObj.getPath(stringIDToTypeID('link'));  

  alert("Layer " + obj.name + ' linked file is"' +  localFilePath + '"');

  }

  catch(e) {}

  return localFilePath;

}

JJMack
hladdha123
Participating Frequently
March 20, 2018

Hi, I also tried getting the localfilepath with the snippet you shared, but do you know how can we replace this localFilepath with a new file or how do we relink it to other file stored on disk programmatically. If you can spare a couple of minutes, can you please have a look at - How to customize the linking file path in recorded photoshop actions. & try to help out .

usx40303570
Participating Frequently
March 20, 2018

Hi

Use this code:

(desc = new ActionDescriptor()).putPath( cTID( "null" ), new File( "C:\\Path\\to\\your\\file.psb" ) );

executeAction( sTID( "placedLayerRelinkToFile" ), desc, DialogModes.NO );

This will replace your selected linked file to another one.