Why is this lua script unable to open a Windows su

2019-09-08 18:03发布

问题:

I'm trying to determine if one of several directories are present from within a lua script. It works on OSX, but not on Windows (linux is currently untested, but I expect that one to work). When the following code runs, I get an error:

failed with this C:\Program Files (x86)\VideoLAN\VLC\lua\playlist\: No such file or directory

I can confirm that that directory exists. I've escaped the slashes, I'm not sure what else could be the issue.

local oses = { "/Applications/VLC.app/Contents/MacOS/share/lua/playlist/"; "C:\\Program Files\\VideoLAN\\VLC\\lua\\playlist\\"; "C:\\Program Files (x86)\\VideoLAN\\VLC\\lua\\playlist\\"; "/usr/lib/vlc/lua/playlist" }

-- Determine which OS this is (and where to find share/lua).
local f,err = io.open( oses[1], "r")
if not err then
    opsys = "OSX"
    scriptpath = oses[1] .. script
    f:close()
else
    f,err = io.open( oses[2], "r")
    if not err then
        opsys = "Win32"
        scriptpath = oses[2] .. script
        f:close()
    else
        f,err = io.open( oses[3], "r")
        vlc.msg.dbg( dhead .. 'failed with this ' .. err .. dtail ) 
        if not err then
            opsys = "Win64"
            scriptpath = oses[3] .. script
            f:close()
        else
            f,err = io.open( oses[4], "r")
            if not err then
                opsys = "Linux/Unix"
                scriptpath = oses[4] .. script
                f:close()
            else
                return false
            end
        end
    end 
end

回答1:

The file "C:\Program Files\VideoLAN\VLC\lua\playlist\" does not exist. If you were to remove the trailing slash, you'd be trying to open a directory and probably get a permissions error. It's not going to work either way. If you're going to use this method of determining OS, you should be trying to open files.

For instance, build your script path, try to open that file, and use that to determine pass/fail.

Side note, the structure of your code could be vastly improved. Any time you have a bunch of duplicate code that differs by an index, you should be using a loop. For instance, we can replace your code with this:

local oses = {
    ["OSX"]        = "/Applications/VLC.app/Contents/MacOS/share/lua/playlist/",
    ["Win32"]      = "C:\\Program Files\\VideoLAN\\VLC\\lua\\playlist\\",
    ["Win64"]      = "C:\\Program Files (x86)\\VideoLAN\\VLC\\lua\\playlist\\",
    ["Linux/Unix"] = "/usr/lib/vlc/lua/playlist",
}
for osname, directory in pairs(oses) do
    local scriptpath = directory..script
    local f,err = io.open( scriptpath, "r")
    if not err then
        f:close()
        return scriptpath, osname
    end
end