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

Update linked smart objects broken file path

Explorer ,
Nov 26, 2018 Nov 26, 2018

Copy link to clipboard

Copied

Our main image folder has been renamed, now many linked smart objects have a wrong path, and when opening the psd, photoshop asks me to update the path.

I would like to run a script and change the path to the new one. Is this even possible?

What I have so far, I can read the file path from a linked smart object like this:

var ref = new ActionReference();

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

var desc = executeActionGet(ref);

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

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

But this will give me the path if the file is correctly linked only. For broken file links getPath(stringIDToTypeID('link') is not available.

Is there a way to read the file path, if the linked file has been moved?

And is it possible to update the path via script then?

TOPICS
Actions and scripting

Views

5.8K

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

People's Champ , Nov 26, 2018 Nov 26, 2018

Try for active layer.

var new_path = "C:\\A1"; // YOUR REAL NEW PATH

var r = new ActionReference();   

r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));

r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

var d = executeActionGet(r); 

if (d.hasKey(stringIDToTypeID("smartObject")))

    {

    d = d.getObjectValue(stringIDToTypeID("smartObject")); 

    if (d.hasKey(stringIDToTypeID("link")))

        {

        var type = d.getT

...

Votes

Translate

Translate
Adobe
People's Champ ,
Nov 26, 2018 Nov 26, 2018

Copy link to clipboard

Copied

var sLocalFilePath = smObj.getString(stringIDToTypeID('link')); 

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
Explorer ,
Nov 26, 2018 Nov 26, 2018

Copy link to clipboard

Copied

getString() works! Do you know how to update the path of the smart object?

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
People's Champ ,
Nov 26, 2018 Nov 26, 2018

Copy link to clipboard

Copied

Try for active layer.

var new_path = "C:\\A1"; // YOUR REAL NEW PATH

var r = new ActionReference();   

r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));

r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

var d = executeActionGet(r); 

if (d.hasKey(stringIDToTypeID("smartObject")))

    {

    d = d.getObjectValue(stringIDToTypeID("smartObject")); 

    if (d.hasKey(stringIDToTypeID("link")))

        {

        var type = d.getType(stringIDToTypeID("link"));

        var pth;

        switch(type)

            {

            case DescValueType.ALIASTYPE:

                pth = d.getPath(stringIDToTypeID("link"));

                break;

            case DescValueType.STRINGTYPE:

                pth = d.getString(stringIDToTypeID("link"));

                break;

            defualt:

                throw("\n\nHmmm!\n\n");

            }

        var file = new File(pth);

        if (!file.exists)

            {

            file = new File(new_path + "/" + file.name);

            var d = new ActionDescriptor();

            d.putPath(stringIDToTypeID("null"), file);

            executeAction(stringIDToTypeID("placedLayerRelinkToFile"), d, DialogModes.NO);

            alert("Done!")

            }

        else

            alert("File already exists");

        }

    else

        {

        alert("No link");

        }

    }

else

    {   

    alert("No smartObject");

    }

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
Explorer ,
Nov 28, 2018 Nov 28, 2018

Copy link to clipboard

Copied

Very nice, thanks!

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
Engaged ,
Feb 25, 2019 Feb 25, 2019

Copy link to clipboard

Copied

r-bin , do you happen to know how to relink on a layer by index? I.e., without making it active.

For instance, I have a SO on index 1, I've tried:

function s2t(s) { return stringIDToTypeID(s) }

var r = new ActionReference();

r.putIndex(s2t('layer'), 1);

var d = executeActionGet(r); // Getting the Layer desc.

var soDesc = d.getObjectValue(s2t('smartObject'));

soDesc.putPath(s2t('link'), new File( "/whatever/new/path/new.jpg" ))

var d1 = new ActionDescriptor();

d1.putObject(s2t('to'), s2t('layer'), soDesc)

executeAction( s2t( "set" ), d1, DialogModes.NO );

With no luck – also because, while I've got the layer by index, I've not been able to specify the target layer idx.

Thanks,

Davide

Davide Barranca - PS developer and author
www.ps-scripting.com

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
Engaged ,
Feb 25, 2019 Feb 25, 2019

Copy link to clipboard

Copied

This code is perhaps more precise, but it doesn't change the link nonetheless...

var r1 = new ActionReference();

var d1 = new ActionDescriptor();

r1.putIndex(s2t('layer'), 1);

d1.putReference(s2t('target'), r1)

var d2 = new ActionDescriptor()

d2.putPath(s2t('link'), new File( "/path/to/whatever/new.jpg" ))

d1.putObject(s2t('to'), s2t('smartObject'), d2)

executeAction( s2t( "set" ), d1, DialogModes.NO );

And it doesn't return any error.

Davide

Davide Barranca - PS developer and author
www.ps-scripting.com

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
People's Champ ,
Feb 25, 2019 Feb 25, 2019

Copy link to clipboard

Copied

There still is the property "fileReference" which, logically, too, would need to be set.
But it also does not work.

I think all the properties of "smartObject" as well as "smartObjectMore" are read-only.

You can not change the property of the document "title" or "depth" for example.

)

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
Advocate ,
Dec 26, 2020 Dec 26, 2020

Copy link to clipboard

Copied

@Davide_Barranca or @r-bin 
Thanks for showing this script about relinking. I had also found this script in another forum post

 

 

 

// find files > auto relink
//  https://community.adobe.com/t5/photoshop/place-linked-using-script/td-p/10205968?page=1
var doc = app.activeDocument;
var fName = doc.name.split(".");
var fName = fName[0];
var layerN = doc.activeLayer.name;
var linkFolder = Folder.selectDialog("Selection prompt");
if(linkFolder !== null){
    var linkFolderPath = linkFolder.path;
    var linkName = linkFolder.name;
    var linkFullPath = linkFolderPath+"/"+linkName;
    //alert("Looking for " + layerN + " in\n" + linkFullPath);
    function traverseFolder(path, layerN)  { 
        var folder = new Folder(path); 
        suffix = new Array();
        suffix[0] = "tif";
        suffix[1] = "dng";
        suffix[2] = "psd";
        suffix[3] = "svg";
        suffix[4] = "jpg";
        var files = folder.getFiles(); 
        for (var i = 0; i < files.length; i++) 
        //alert(files[i] instanceof File)
        { 
            if (files[i] instanceof File) 
            {  
                var fullPathName = Folder.decode(files[i]);
                //alert(fullPathName)
                var fileName = files[i].name;
                fileName = decodeURI(fileName);
                //alert(fileName)
                for(var s = 0; s < suffix.length ; s++){
                    search_name = layerN + "." + suffix[s];
                    search_NAME = layerN + "." + suffix[s].toUpperCase();
                    if ((fileName == search_name) || (fileName == search_NAME)) 
                    { 
                        foundFile = fullPathName + "/" + fileName;
                        alert("Found: " + foundFile); 
                        relinkFile(foundFile)
                        return foundFile ;
                    }
                }
            } 
            else 
            { 
               traverseFolder(files[i], layerN); 
               // return traverseFolder(files, layerN); 
            } 
        } 
    }
    function cTID(s) { return app.charIDToTypeID(s); };
    function sTID(s) { return app.stringIDToTypeID(s); };
    function relinkFile(foundFile){
        alert(typeof(foundFile))
        file = new File(foundFile);
        //file = new File(new_path + "/" + file.name);
        var desc475 = new ActionDescriptor();
        //desc475.putPath( cTID('null'), new File( file ) );
        desc475.putPath( cTID('null'), new File( "D:\_MINDFLOW\CLIENTS\Allusion\Design\Recourses\Icons-24x\more.svg" ) );
        //executeAction( sTID('placedLayerRelinkToFile'), desc475, DialogModes.NO );// replace link
        executeAction( sTID('placedLayerReplaceContents'), desc475, DialogModes.NO );// replace content
        //https://community.adobe.com/t5/photoshop/place-linked-using-script/td-p/10205968?page=2
    //     var idplacedLayerRelinkToFile = stringIDToTypeID( "placedLayerRelinkToFile" );
    //     var desc121 = new ActionDescriptor();
    //     var idnull = charIDToTypeID( "null" );
    //     desc121.putPath( idnull, new File( foundFile ) );
    //     executeAction( idplacedLayerRelinkToFile, desc121, DialogModes.NO );
    }

    var foundFile = traverseFolder(linkFullPath, layerN);
    alert("Found: " + foundFile);
}

 

 

Minus my trial and error codes i added to catch patch etc.

In both of the version i believe no dialog should show right? i see DialogModes.NO. Does any one know if this perhaps due the nature of that function? 
Im also trying to bulk rellink images in a PSD file. My reason is that i work on both Windows as OSX since 2-3 weeks. Now lots of my design cause issues because the different paths 😞

The the great thing abou tthis example scripts is that it cycles through the files and if its the same it will relink. However it still promts for relinking the image, kinda destroys the use of the script. 

 

I also tried using scriptlistener and then fix the script making it read easier. Again it will show the dialog.

After typing this i tried on more go, this time using the original scriptlistener output. This however seems to work just fine. Now im wondering why the cleaned version does show a dialog?!?!

 

// =======================================================
var idplacedLayerReplaceContents = stringIDToTypeID( "placedLayerReplaceContents" );
    var desc539 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
    desc539.putPath( idnull, new File( "D:\\_MINDFLOW\\CLIENTS\\Allusion\\Design\\Recourses\\Icons-24x\\more.svg" ) );
executeAction( idplacedLayerReplaceContents, desc539, DialogModes.NO );

 

 

EDIT 2

ow now i see, the paths have double backslashes, is that to escape them or so?
So perhaps when i use some kind of regex or replace function i could fix the path. Lets hope that works.

Would be nice if i eventually end up with a version similar to one of InDesign, there you can point to a folder and will automatically link all the missing links.

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
Advocate ,
Dec 26, 2020 Dec 26, 2020

Copy link to clipboard

Copied

okay got it working now. perhaps i need to tweak it a bit more and fine tune it. I used parts of the layercomps script from photoshop to go over the selected layers. Combined with parts of that other scripts, i striped out his method for getting path because that was actually causing the issues. The wrong usage of the back and forward slashes. 

 

i paste it here so it can perhaps help other in need. I have not done time trials on it to see where i could speed things up. Would be interesting to see. I believe that the function which gets the layer info already loops over the layers, we could already do the linking there i guess. Perhaps ill try a variant of this one and do some test with say 100 missing links or so. I got some interesting results on a different script i made. There i used the time trials to decide wether or not to show progress bar. On OSX thats one big headache since it needs to refresh the app and that slows it down A LOT!!

 

 

Ive added some extra parts so it show in the main menu of script sub menu

restore-missing-links.png

 

// Collection of scripts i gathered for quick relinken missing images
// Rombout Versluijs Dec 2020


/*
@@@BUILDINFO@@@ Restore Missing Links.jsx 0.0.0.7
*/
/*
// BEGIN__HARVEST_EXCEPTION_ZSTRING
/*
<javascriptresource>
<name>$$$/JavaScripts/RestoreMissingLinks/Menu=Restore Missing Links...</name>
<category>aaaThisPutsMeAtTheTopOfTheMenu</category>
//<category>Restore</category>
<enableinfo>true</enableinfo>
</javascriptresource>

// END__HARVEST_EXCEPTION_ZSTRING

*/


#target photoshop

// var docName = app.activeDocument.name;
// app.activeDocument = app.documents[docName];
docRef = app.activeDocument;

//var new_path = "D:\\_MINDFLOW\\CLIENTS\\Allusion\\Design\\Recourses\\Icons-24x"; // YOUR REAL NEW PATH
//alert(new_path)
function cTID(s) { return app.charIDToTypeID(s); };
function sTID(s) { return app.stringIDToTypeID(s); };


///////////////////////////////////////////////////
// Get Layer Kind
// https://www.ps-scripts.com/viewtopic.php?p=43242#p43242
// Get return layerkind by layerid
///////////////////////////////////////////////////
function getLayerKindByIndex(index) {
    var ref, desc, adjustmentDesc, layerSectionType;
    ref = new ActionReference();
    ref.putIndex(charIDToTypeID("Lyr "), index);
    desc = executeActionGet(ref);
    var layerType = typeIDToStringID(desc.getEnumerationValue(stringIDToTypeID('layerSection')));
    if (layerType != 'layerSectionContent') return; // return if layerSet
    if (desc.hasKey(stringIDToTypeID('textKey'))) return LayerKind.TEXT;
    if (desc.hasKey(stringIDToTypeID('smartObject'))) return LayerKind.SMARTOBJECT; // includes LayerKind.VIDEO
    if (desc.hasKey(stringIDToTypeID('layer3D'))) return LayerKind.LAYER3D;
    if (desc.hasKey(stringIDToTypeID('videoLayer'))) return LayerKind.VIDEO;
    if (desc.hasKey(stringIDToTypeID('adjustment'))) {
        switch (typeIDToStringID(desc.getList(stringIDToTypeID('adjustment')).getClass(0))) {
            case 'photoFilter':
                return LayerKind.PHOTOFILTER;
            case 'solidColorLayer':
                return LayerKind.SOLIDFILL;
            case 'gradientMapClass':
                return LayerKind.GRADIENTMAP;
            case 'gradientMapLayer':
                return LayerKind.GRADIENTFILL;
            case 'hueSaturation':
                return LayerKind.HUESATURATION;
            case 'colorLookup':
                return udefined; //this does not exist and errors with getting layer kind
            case 'colorBalance':
                return LayerKind.COLORBALANCE;
            case 'patternLayer':
                return LayerKind.PATTERNFILL;
            case 'invert':
                return LayerKind.INVERSION;
            case 'posterization':
                return LayerKind.POSTERIZE;
            case 'thresholdClassEvent':
                return LayerKind.THRESHOLD;
            case 'blackAndWhite':
                return LayerKind.BLACKANDWHITE;
            case 'selectiveColor':
                return LayerKind.SELECTIVECOLOR;
            case 'vibrance':
                return LayerKind.VIBRANCE;
            case 'brightnessEvent':
                return LayerKind.BRIGHTNESSCONTRAST;
            case 'channelMixer':
                return LayerKind.CHANNELMIXER;
            case 'curves':
                return LayerKind.CURVES;
            case 'exposure':
                return LayerKind.EXPOSURE;
                // if not one of the above adjustments return - adjustment layer type
            default:
                return typeIDToStringID(desc.getList(stringIDToTypeID('adjustment')).getClass(0));
        }
    }
    return LayerKind.NORMAL; // if we get here normal should be the only choice left.
};



/// ////////////////////////////////////////////////////////////////////////////
// Function: Combination of applyToAllLayersAMIdx & getLayerInfo
// Usage: extract a list of index values of all the selected layers & ID layernamer
// Input:: (active document.) s
// Return: array of indexes ID"s of selected layers.
// Mixed this so it only loops once over all layers
/// ////////////////////////////////////////////////////////////////////////////
function applyToAllLayersInfo(docRef) {
    // alert(docRef)
    var selectedLayers = new Array()
    var ref = new ActionReference()
    // get a number list of selected artLayers in the document
    ref.putProperty(app.charIDToTypeID("Prpr"), stringIDToTypeID("targetLayers"))
    ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"))
    // what do I want to do this this list? Define an description of an action.
    var desc = executeActionGet(ref)
    // if the selected object has the "Target Layers" key (only works CS4+)
    if (desc.hasKey(stringIDToTypeID("targetLayers"))) {
        desc = desc.getList(stringIDToTypeID("targetLayers"))
        var c = desc.count
        var selectedLayers = [] // for each
        for (var i = 0; i < c; i++) {
            var lyr = {}
            var lyrIndex;
            try {
                docRef.backgroundLayer // try to select a background layer, if I can then adjust the index counting. (Background layers change index counitng of all layers by 1)
                // selectedLayers.push(desc.getReference(i).getIndex())
                lyrIndex = desc.getReference(i).getIndex();
            } catch (e) {
                // selectedLayers.push(desc.getReference(i).getIndex() + 1)
                lyrIndex = desc.getReference(i).getIndex() + 1;
            }
            // Added from getLayerInfo
            var lyrRef = new ActionReference();
            lyrRef.putIndex(charIDToTypeID("Lyr "), lyrIndex)
            var lyrDesc = executeActionGet(lyrRef);
            // alert(lyrDesc.getInteger(stringIDToTypeID("layerKind")))
            var Id = lyrDesc.getInteger(stringIDToTypeID("layerID"));
            lyr.AMid = Id;
            lyr.lyrKind = getLayerKindByIndex(lyrIndex);
            lyr.lyrIndex = lyrIndex;
            selectedLayers.push(lyr);
        }
    }
    return selectedLayers
}



///////////////////////////////////////////////////
// Select Layer by LayerIndex
// Source: https://stackoverflow.com/questions/26295492/photoshop-script-new-layer-below-current-layer
// select [LayerNum], optionally [add] to selection (if add=2: with inclusion)
///////////////////////////////////////////////////
function selLyr(LyrN, add) {
    var adesc = new ActionDescriptor();
    var aref = new ActionReference();
    aref.putIndex(charIDToTypeID("Lyr "), LyrN);
    adesc.putReference(charIDToTypeID("null"), aref);
    if (add) {
        add = (add == 2) ? stringIDToTypeID("addToSelectionContinuous") : stringIDToTypeID("addToSelection");
        adesc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), add);
    }
    adesc.putBoolean(charIDToTypeID("MkVs"), false);
    return executeAction(charIDToTypeID("slct"), adesc, DialogModes.NO);
}



///////////////////////////////////////////////////
// Select Layers by LayerID
// Source: https://graphicdesign.stackexchange.com/questions/130739/photoshop-scripting-applying-changes-only-to-selected-artboards
///////////////////////////////////////////////////
function selectById(AMid) {
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putIdentifier(charIDToTypeID('Lyr '), AMid);
    desc1.putReference(charIDToTypeID('null'), ref1);
    executeAction(charIDToTypeID('slct'), desc1, DialogModes.NO);
}


/// ////////////////////////////////////////////////////////////////////////////
// Function: getSelectedLayersAMIdx
// Usage: extract a list of index values of all the selected layers.
// Input:: (active document.) s
// Return: array of indexes ID"s of selected layers.
/// ////////////////////////////////////////////////////////////////////////////
function getSelectedLayersAMIdx(docRef) {
    var selectedLayers = new Array()
    var ref = new ActionReference()
    // get a number list of selected artLayers in the document
    ref.putProperty(app.charIDToTypeID("Prpr"), stringIDToTypeID("targetLayers"))
    ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"))
    // what do I want to do this this list? Define an description of an action.
    var desc = executeActionGet(ref)
    // if the selected object has the "Target Layers" key (only works CS4+)
    if (desc.hasKey(stringIDToTypeID("targetLayers"))) {
        desc = desc.getList(stringIDToTypeID("targetLayers"))
        var c = desc.count
        var selectedLayers = [] // for each
        for (var i = 0; i < c; i++) {
            try {
                docRef.backgroundLayer // try to select a background layer, if I can then adjust the index counting. (Background layers change index counitng of all layers by 1)
                selectedLayers.push(desc.getReference(i).getIndex())
            } catch (e) {
                selectedLayers.push(desc.getReference(i).getIndex() + 1)
            }
        }
    }
    return selectedLayers
}



/// ////////////////////////////////////////////////////////////////////////////
// Function: relinkFiles
// Usage: relinks path to missing linked image.
// Input:: string of path to found image
// Return: correct linked image
// source: https://community.adobe.com/t5/photoshop/update-linked-smart-objects-broken-file-path/m-p/11707888?page=1#M213131
/// ////////////////////////////////////////////////////////////////////////////
function relinkFiles() {
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));
    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    var d = executeActionGet(r);
    if (d.hasKey(stringIDToTypeID("smartObject"))) {
        d = d.getObjectValue(stringIDToTypeID("smartObject"));
        if (d.hasKey(stringIDToTypeID("link"))) {
            var type = d.getType(stringIDToTypeID("link"));
            var pth;
            switch (type) {
                case DescValueType.ALIASTYPE:
                    pth = d.getPath(stringIDToTypeID("link"));
                    break;
                case DescValueType.STRINGTYPE:
                    pth = d.getString(stringIDToTypeID("link"));
                    break;
                default:
                    throw ("\n\nHmmm!\n\n");
            }
            var file = new File(pth);
            if (!file.exists) {
                file = new File(new_path + "\\" + file.name);
                var d = new ActionDescriptor();
                d.putPath(stringIDToTypeID("null"), file);
                //executeAction(stringIDToTypeID("placedLayerRelinkToFile"), d, DialogModes.NO);// replace link
                executeAction(stringIDToTypeID("placedLayerReplaceContents"), d, DialogModes.NO); // replace content
                alert("Done!")
            } else
                alert("File already exists");
        } else {
            alert("No link");
        }
    } else {
        alert("No smartObject");
    }
}


/// ////////////////////////////////////////////////////////////////////////////
// Function: searchFolder
// Usage: prompt for folder and loop over files
// Input:: folder path
// Return: correct linked image
// source: https://community.adobe.com/t5/photoshop/place-linked-using-script/td-p/10205968?page=1
/// ////////////////////////////////////////////////////////////////////////////
var linkFolder = Folder.selectDialog("Selection prompt");
// alert(linkFolder)
function searchFolder(){
    var layerN = docRef.activeLayer.name;
    if(linkFolder !== null){
        var linkFolderPath = linkFolder.path;
        var linkName = linkFolder.name;
        var linkFullPath = linkFolderPath+"/"+linkName;
        function traverseFolder(path, layerN)  { 
            var folder = new Folder(path); 
            suffix = new Array();
            suffix[0] = "tif";
            suffix[1] = "dng";
            suffix[2] = "psd";
            suffix[3] = "svg";
            suffix[4] = "jpg";
            var files = folder.getFiles(); 
            for (var i = 0; i < files.length; i++) { 
                if (files[i] instanceof File) {  
                    var fullPathName = Folder.decode(files[i]);
                    //alert(fullPathName)
                    var fileName = files[i].name;
                    //alert(fileName)
                    fileName = decodeURI(fileName);
                    //alert(fileName)
                    for(var s = 0; s < suffix.length ; s++){
                        search_name = layerN + "." + suffix[s];
                        search_NAME = layerN + "." + suffix[s].toUpperCase();
                        if ((fileName == search_name) || (fileName == search_NAME)) 
                        { 
                            foundFile = fullPathName + "/" + fileName;
                            //alert("Found: " + foundFile); 
                            //alert("Found: " + files[i]); 
                            relinkFile(files[i])
                            return files[i] ;
                        }
                    }
                } else { 
                traverseFolder(files[i], layerN); 
                // return traverseFolder(files, layerN); 
                } 
            } 
        }
        
        function relinkFile(foundFile){
            var d = new ActionDescriptor();
            d.putPath( cTID('null'), new File( foundFile ) );
            executeAction(stringIDToTypeID("placedLayerRelinkToFile"), d, DialogModes.NO);// replace link
            // executeAction( sTID('placedLayerReplaceContents'), d, DialogModes.NO );// replace content
        }
        var foundFile = traverseFolder(linkFullPath, layerN);
        //alert(foundFile)
    }
}

var layerInfo = applyToAllLayersInfo(docRef);
for (var i = 0; i < layerInfo.length; i++) {
    selectById(layerInfo[i].AMid);
    searchFolder()
}

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
Advocate ,
Dec 26, 2020 Dec 26, 2020

Copy link to clipboard

Copied

the path needs double backward slashes for windows, is that osx your on?

If you alert the path it will show single slashes, but when i check scriptlistener i noticed the OS itself puts 2 slahes in the extend script.

 

see below test run

// =======================================================
var idplacedLayerReplaceContents = stringIDToTypeID( "placedLayerReplaceContents" );
    var desc539 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
    desc539.putPath( idnull, new File( "D:\\_MINDFLOW\\CLIENTS\\Allusion\\Design\\Recourses\\Icons-24x\\more.svg" ) );
executeAction( idplacedLayerReplaceContents, desc539, DialogModes.NO );

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
Advocate ,
Dec 26, 2020 Dec 26, 2020

Copy link to clipboard

Copied

I tried making my altered version of the script using parts of the layercomp exporter work. 
I think relinking without making it active wont work. I can loop over the layers and get all the data, but as soon as i throw in that relink function in that loop i returns this error.

 

error-relink-byindex-withoutactive.png

 

Would be so nice if it could be done, because that saves quite some time. I know need to loop over everything 2 or 3 times to get it to work.

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
LEGEND ,
Oct 03, 2020 Oct 03, 2020

Copy link to clipboard

Copied

Is there a way to read / write system path of linked layer that is in Smart Object, without opening that SO? Precisely: Document -> Placed Layer (SO) -> Linked Layer (SO)

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
People's Champ ,
Oct 03, 2020 Oct 03, 2020

Copy link to clipboard

Copied

I think only parsing the entire PSD.
Find the Placed object for the desired smart object and then do the next parsing of its layers.
 
UPD.
You can also parse the exported content of the smart object
 

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
LEGEND ,
Oct 04, 2020 Oct 04, 2020

Copy link to clipboard

Copied

I was affraid reading binaries is currently only one method to do it. Then I thought of exporting SO to accelerate parsing, but still not that perhaps one future day Adobe would bring to scripting land!

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
Enthusiast ,
Jul 10, 2023 Jul 10, 2023

Copy link to clipboard

Copied

Am I correct to assume if the path is empty the link is considered missing? Otherwise wondering, is there a link status attribute?

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
Explorer ,
Nov 07, 2020 Nov 07, 2020

Copy link to clipboard

Copied

Error 8800: General Photoshop error occured. This functionality may not be avalilable in this version of Photoshop.

- The command "Relink to File" is not currently available;

Line 59

-> executeAction(stringIDToTypeID("placedLayerRelinkToFile"), d, DialogModes.NO);

 

I am using Photoshop CC 2017 2017.0.0 Release. Any update how to resolve the above issue?

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
People's Champ ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Is the required layer active?

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
Explorer ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Active means visible? If so, Yes...they are visible.

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
People's Champ ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

active - means selected.
Also answer the question about new_path
 

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
Explorer ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Yes... selected...There are 36 image files at the psb file which I am currently testing.... All are selected by Clicking 1st layer + Shift + Last layer.

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
Explorer ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Yes...that was my fault... I forgot to rename the new path... I will test it tomorrow and let you know because it is night time here. 

Thankyou

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
People's Champ ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

No, you only need to select one layer.
If several are selected, then the script will work only with the topmost one.
 

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
Explorer ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Ok, thank you for the clarification... This was a great clarification.

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
Explorer ,
Nov 08, 2020 Nov 08, 2020

Copy link to clipboard

Copied

Then what will happen, suppose I have linked object from 3 separate folders/directories. Now if without selection, the script works, then it will replace all the linked object to one specific folder stated at new_path, no matter the layers are selected or not. Then all will be relinked to one path only... but if I have 3 paths, will it be right?

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