PHP:如何确定文件是否是Windows平台上的快捷方式?

时间:2011-04-11 00:21:09

标签: php windows shortcuts

排除尚未与PHP捆绑的任何第三方扩展程序,是否有任何方法可以确定Windows计算机上的给定文件是否为快捷方式/链接?内置函数is_link仅适用于* nix平台,因此在Windows机器上运行的以下内容将不会返回预期的内容:

$filePath = 'C:\somefile.lnk'; // path to shortcut file
var_dump(is_file($filePath)); // returns true
var_dump(is_link($filePath)); // returns false

这会在尝试使用快捷方式的目标文件时导致问题,并最终在快捷方式文件本身上运行。快捷方式的前四个字节通常是4c 00 00 00。但是这个开放字节序列始终仅限于快捷方式似乎不可靠。

附带问题:如何从快捷方式文件中提取目标路径? (注意:readlink()似乎返回快捷方式文件本身的路径。)

编辑:只是为了省去一些麻烦,根据PHP使用finfomime_content_type的mime类型的快捷方式文件是“application / octet-stream”,其中真的无济于事。

1 个答案:

答案 0 :(得分:1)

就像填写答案一样。几年前写的,不确定它是否适用于当前的Windows版本。

要检查魔术字节,只需使用:

 $bin = file_get_contents("file.lnk", 2048);
 if (substr($bin, 0, 20) == "L\000\000\000\001\024\002\000\000\000\000\000\300\000\000\000\000\000\000F") {

如果你想提取路径:

  function decode_windows_visual_shortcut($bin) {

            # taken from "The Windows Shortcut File Format.pdf" V1.0 as
            # reverse-engineered by Jesse Hager <jessehager@iname.com> 

            if (!defined("WIN_LNK_F_ITEMLIST")) {

                    define("WIN_LNK_F_ITEMLIST", 1);
                    define("WIN_LNK_F_FILE", 2);
                    define("WIN_LNK_F_DESC", 4);
                    define("WIN_LNK_F_RELATIVE", 8);
                    define("WIN_LNK_F_WORKDIR", 16);
                    define("WIN_LNK_F_CMDARGS", 32);
                    define("WIN_LNK_F_ICON", 64);   
                    define("WIN_LNK_F2_DIR", 16);   

                    function bread(&$bin, &$p, $bytes=4) {
                            $h = bin2hex( strrev($s = substr($bin, $p, $bytes)) );
                            $v = base_convert($h, 16, 10);
                            $p += $bytes;
                            return($v);  
                    }
            }

            $res = array();
            $p = 0x14;
            $fl=$res["flags"] = bread($bin,$p);
            $res["t_attr"] = bread($bin,$p);   
            $p = 0x4C;

            if ($fl & WIN_LNK_F_ITEMLIST) {
                    #-- don't need this
                    $p += bread($bin,$p,2);
            }

            if ($fl & WIN_LNK_F_FILE) {
                    #-- File Location Info
                    $p0 = $p;
                    $p = $p0 + 0x10;
                    $p_path = $p0 + bread($bin,$p);
                    $p = $p0 + 0x18;
                    $p_file = $p0 + bread($bin,$p);
                    $path = substr($bin, $p_path, 704);
                    $path = substr($path, 0, strpos($path, "\000"));
                    $file = substr($bin, $p_file, 704);
                    $file = substr($file, 0, strpos($file, "\000"));
                    $res["path"] = $path;
                    $res["file"] = $file;
            }

            return($res);
    }

http://code.google.com/p/8bits/downloads/detail?name=The_Windows_Shortcut_File_Format.pdf