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
  • 7629 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
Participating Frequently
January 20, 2023

John, 

The original processSmartObj function used to work but no longer does, could this bve due to an update in Photoshop? If so I don't suppose you or someone else could probvided a function that does the same thing?

Thanks
Anthony

Legend
January 20, 2023

Looks like it is returned on the 'link' variable:

{"_obj":"object","smartObject":{"_obj":"smartObject","compsList":{"compID":-1,"originalCompID":-1},"documentID":"","fileReference":"3793_04_D25066.m_VrayNormals.0000.png","link":"N:\\3793_Albert_Swedish_Wharf_Planning_Updates\\Data\\Compositing\\Renders\\02_Main_Views\\04_D25066\\Latest\\3793_04_D25066.m_VrayNormals.0000.png","linkChanged":false,"linkMissing":true,"linked":true,"placed":{"_enum":"placed","_value":"rasterizeContent"}}}


@Anthony L. Cityscape, try this: 

 

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.getType(stringIDToTypeID('link')) == DescValueType.ALIASTYPE ?
      smObj.getPath(stringIDToTypeID('link')) : new File(smObj.getString(stringIDToTypeID('link')))
    alert("Layer " + obj.name + ' linked file is"' + localFilePath + '"');
  }
  catch (e) { }
  return localFilePath;
}

 

to @r-bin , тебе встречались ситуации, когда путь к смарт-объекту был в виде string, а не в виде пути? Это можно как-то вопроизвести?