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
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

Participating Frequently
January 20, 2023

Are you using macOS? The fact is that when opening a file, the paths of lost smart objects in Windows and macOSare interpreted differently (Photoshop in windows saves the path to the file, Photoshop for macOSloses the path to the file, but leaves its name)


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.getString(stringIDToTypeID('fileReference'));
        alert("Layer " + obj.name + ' linked file is"' + localFilePath + '"');
    }
    catch (e) { }
    return localFilePath;
}

 

You can also look at the topic in which I suggested a script to update the lost paths of linked smart objects:  Is there an option that shows me a list with all smart objects paths?  (I don’t remember how up-to-date the code is, the latest version is available in my github repository Layers -> Layers - relink layers 2.jsx)

 

 


Thanks, using windows.

That function now returns the file name which is what I'm looking for. - thank-you. 

Inceidently I found you Linked_Files Script this morning, looks great, unfortunatly I couldn't us it for my sceneario as the the file name actually changes eg.  3912_04_D25066.Alpha.0000.png would change to  4930_04_D25066.Alpha.0000.png 

Thanks for your help