Windows客户端开发

【Windows】shortcut、hard link、junc

2016-11-23  本文已影响77人  mercurygear

问题导致的需求

最近的工作上有个升级COM组件的需求,但是我们这个COM组件每次注册的时候,其对应的dll路径及文件名是固定不变的;

这就遇到了一个状况,如果该dll正在被加载使用中,如何去替换它呢?(当然,如果注册的时候允许dll变更文件名就没有这个困扰)

正在被使用中的文件进行删除操作是会失败的,所以不可能通过拷贝覆盖的方法来做,当时的第一念头就是通过symbolic link来完成这个事情。

只要后续我们这个注册表中指向的固定路径是一个symbolic link,那么一旦有升级的需求,只需要拷贝升级dll到同个目录下(当然要进行改名以避免同名dll使用中导致无法覆盖的情况),删除原symbolic link,创建过一个新的同名symbolic link,但是其指向升级dll即可。

这个方案在vista及以上的系统是没有问题的,但是由于xp不支持symbolic link,所以上述方案最终还是没有实施,而是换过了另外一套方案,跟本文的主题无关,这里就不详述了,有空会再写一篇文章来总结这个事情。

下面还是回到正题上来,探讨Windows下的几种链接形式,以下的文字大部分引用了这篇文章《Windows硬链接 软链接 符号链接 快捷方式》

shortcut(快捷方式)

hard link(硬链接)

CreateHardLink()
CreateHardLinkTransacted()
mklink /H "hard link name" "target file"
fsutil.exe hardlink create "hard link name" "target file"
fsutil.exe hardlink list "hard link name"
fsutil.exe hardlink list "target file"

junction point/soft link/reparse point

Hard Links and Junctions
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365006

Reparse Points
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365503
Junction v1.06
http://www.sysinternals.com
http://technet.microsoft.com/en-us/sysinternals/default.aspx
https://technet.microsoft.com/en-us/sysinternals/bb896768
How to create and manipulate NTFS junction points
https://support.microsoft.com/en-us/kb/205524

diskmgmt.msc
    右键选中某volume
        更改驱动器号和路径
            添加
                装入以下空白NTFS文件夹中
这个功能用的就是junction point机制,还可以用mountvol.exe完成操作。
mklink /J "junction point name" "target directory"      // 生成的Reparse Data相比junction.exe要多
linkd.exe "junction point name" "target directory"      // Windows Resource Kits
dir /A:L /S "path"
fsutil.exe reparsepoint query "junction point name"     // 有Reparse Data的16进制转储
linkd.exe "junction point name"                         // 不能查看junction.exe生成的"junction point"
fsutil.exe reparsepoint delete "junction point name"    // 不建议使用
linkd.exe "junction point name" /D                      // 可以删除junction.exe生成的"junction point"
它这个行为不是我们期望的效果,比如"target directory"下有普通文件,
上述命令会删除"junction point"下的普通文件,但不会删除"junction point",
同时"target directory"下的普通文件仍然存在。这个效果我不能理解。
在Explorer中操作无法达到这种效果。
junction.exe "junction point name" "target directory"   // 创建
junction.exe "junction point name"                      // 查看
junction.exe -q -s "path"                               // 递归查看
junction.exe -d "junction point name"                   // 删除 
我猜junction.exe提供-d参数,就是因为Windows 2000/XP/2003的Explorer奇葩行为,
这个-d不影响target directory。  
示例: 
"dir /A:L /S c:\
2009/07/14  13:08    "JUNCTION"     Documents and Settings [C:\Users]
"junction.exe "C:\Documents and Settings"
C:\Documents and Settings: JUNCTION
   Print Name     : C:\Users
   Substitute Name: C:\Users
"junction.exe -q -s c:\
\\?\c:\\Documents and Settings: JUNCTION
   Print Name     : C:\Users
   Substitute Name: C:\Users

symbolic link

Symbolic Links
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680

CreateSymbolicLink()
CreateSymbolicLinkTransacted()
mklink "file symbolic link name" "target file"
mklink /D "directory symbolic link name" "target directory"
注意不指定/D时创建file symbolic link,指定/D创建directory symbolic link。
上一篇 下一篇

猜你喜欢

热点阅读