You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lightroom Lua插件报错:调用isDirectory字段为nil值,求解决方案

Lightroom Lua插件报错排查:attempt to call field 'isDirectory' (a nil value)

问题说明

刚接触Lua,开发Lightroom插件实现遍历文件夹结构并创建Published Collection Set(后续扩展为智能集合组),运行插件时触发错误:

[string "main.lua"]:49: attempt to call field 'isDirectory' (a nil value)

插件代码如下:

-- main.lua

-- Import Lightroom SDK modules
local LrDialogs     = import 'LrDialogs'
local LrTasks       = import 'LrTasks'
local LrApplication = import 'LrApplication'
local LrPathUtils   = import 'LrPathUtils'
local LrFileUtils   = import 'LrFileUtils'

-- Run the task asynchronously to avoid blocking the UI
LrTasks.startAsyncTask(function()
    -- Prompt the user to select a folder
    local selection = LrDialogs.runOpenPanel({
        title = "Select a folder to create a Published Collection Set tree",
        canChooseFiles = false,
        canChooseDirectories = true,
        allowsMultipleSelection = false,
    })

    if not selection or #selection == 0 then
        return
    end
    local rootPath = selection[1]

    -- Get the active catalog and choose a publish service
    local catalog = LrApplication.activeCatalog()
    local services = catalog:getPublishServices()
    if #services == 0 then
        LrDialogs.message("Error", "No Publish Services found. Please create or enable a Publish Service first.")
        return
    end
    local service = services[1]

    -- Table to collect processed folder names for debugging
    local processed = {}

    -- Recursive function to create Published Collection Sets
    local function createSets(path, parentSet)
        -- Create a set for this folder under the given parent (or top-level if nil)
        local name = LrPathUtils.leafName(path)
        local newSet = service:createPublishedCollectionSet(name, parentSet)
        table.insert(processed, name)

        -- Iterate through directory entries and recurse into directories only
        for entry in LrFileUtils.directoryEntries(path) do
            if entry ~= "." and entry ~= ".." then
                local childPath = LrPathUtils.child(path, entry)
                -- Only process if this entry is a directory
                if LrFileUtils.isDirectory(childPath) then
                    -- Debug popup for each subfolder
                    LrDialogs.message("Processing subfolder:", childPath)
                    createSets(childPath, newSet)
                end
            end
        end
    end

    -- Build the tree inside a write-access block
    catalog:withWriteAccessDo("Create Published Collection Set Tree", function()
        createSets(rootPath, nil)
    end)

    -- Show summary of processed folders
    if #processed > 0 then
        LrDialogs.message("Processed folders:", table.concat(processed, "\n"))
    else
        LrDialogs.message("No folders processed.")
    end
end)

错误原因

Lightroom SDK的LrFileUtils模块中没有isDirectory方法,你混淆了其他语言/框架的API命名。在Lightroom Lua SDK里,判断路径是否为目录的正确方法是LrFileUtils.isFolder()。

修复方案

将代码中LrFileUtils.isDirectory(childPath)替换为LrFileUtils.isFolder(childPath),同时建议先判断路径是否存在,避免因无效路径触发异常。

修改后的完整代码

-- main.lua

-- Import Lightroom SDK modules
local LrDialogs     = import 'LrDialogs'
local LrTasks       = import 'LrTasks'
local LrApplication = import 'LrApplication'
local LrPathUtils   = import 'LrPathUtils'
local LrFileUtils   = import 'LrFileUtils'

-- Run the task asynchronously to avoid blocking the UI
LrTasks.startAsyncTask(function()
    -- Prompt the user to select a folder
    local selection = LrDialogs.runOpenPanel({
        title = "Select a folder to create a Published Collection Set tree",
        canChooseFiles = false,
        canChooseDirectories = true,
        allowsMultipleSelection = false,
    })

    if not selection or #selection == 0 then
        return
    end
    local rootPath = selection[1]

    -- Get the active catalog and choose a publish service
    local catalog = LrApplication.activeCatalog()
    local services = catalog:getPublishServices()
    if #services == 0 then
        LrDialogs.message("Error", "No Publish Services found. Please create or enable a Publish Service first.")
        return
    end
    local service = services[1]

    -- Table to collect processed folder names for debugging
    local processed = {}

    -- Recursive function to create Published Collection Sets
    local function createSets(path, parentSet)
        -- Create a set for this folder under the given parent (or top-level if nil)
        local name = LrPathUtils.leafName(path)
        local newSet = service:createPublishedCollectionSet(name, parentSet)
        table.insert(processed, name)

        -- Iterate through directory entries and recurse into directories only
        for entry in LrFileUtils.directoryEntries(path) do
            if entry ~= "." and entry ~= ".." then
                local childPath = LrPathUtils.child(path, entry)
                -- 先判断路径存在,再判断是否为目录
                if LrFileUtils.exists(childPath) and LrFileUtils.isFolder(childPath) then
                    -- Debug popup for each subfolder
                    LrDialogs.message("Processing subfolder:", childPath)
                    createSets(childPath, newSet)
                end
            end
        end
    end

    -- Build the tree inside a write-access block
    catalog:withWriteAccessDo("Create Published Collection Set Tree", function()
        createSets(rootPath, nil)
    end)

    -- Show summary of processed folders
    if #processed > 0 then
        LrDialogs.message("Processed folders:", table.concat(processed, "\n"))
    else
        LrDialogs.message("No folders processed.")
    end
end)

额外提示

  • 开发Lightroom插件时,务必对照官方SDK文档确认API名称,避免混用其他环境的方法名
  • 递归遍历文件夹时,增加路径存在性判断可以提升代码稳定性,处理如权限限制、临时文件消失等场景

内容的提问来源于stack exchange,提问作者Keymaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:13:17