//lnk 快捷方式 import fsys; import fsys.version; import util.metaProperty; import com.interface.IShellLink; import inet.url; import string.res; namespace fsys; class lnk { ctor(){ this.$shellLink = ..com.interface.create("{00021401-0000-0000-C000-000000000046}",..com.interface.IShellLink ); this.$persistFile = this.$shellLink.QueryInterface(..com.interface.IPersistFile) this.$defaultExt = ".lnk"; }; @_metaProperty; } lnk._metaProperty = ..util.metaProperty( load = function(path){ if( !path ) error("请指定快捷方式文件路径",2); var hr = owner.$persistFile.Load( ..io.fullpath( path ) ,0); if( (hr)<0/*FAILED*/ ) return false,..lasterr(hr); owner.filename = ..io.splitpath(path).file; owner.filepath = path; return owner; }; save = function(path){ if( !#path ) { path = owner.filepath; if( !#path ) error("请指定存储路径",2); }; if( ..fsys.isDir(path) ){ var filename = owner.filename; if( !#filename ) error("未指定快捷方式存储文件名或目标路径",2); path = ..io.joinpath(path,filename); } var hr = owner.$persistFile.Save( ..io.fullpath(path) ,true); if( (hr)<0/*FAILED*/ ) return false,..lasterr(hr); owner.filepath = path; return true; }; getIcon = function(){ var hr,location,index = owner.$shellLink.GetIconLocation(1024*2,1024,0); if( (hr)<0/*FAILED*/ ) return false,..lasterr(hr); return location,index; }; setIcon = function(location,index){ if( ..io.localpath(location) ) target = ..io.fullpath(location); var hr = owner.$shellLink.SetIconLocation(location,index : 0); if( (hr)<0/*FAILED*/ ) return false,..lasterr(hr); return true; }; resolve = function(hwnd,flags){ var hr = owner.$shellLink.Resolve(hwnd:0,flags : 0); if( (hr)<0/*FAILED*/ ) return false,..lasterr(hr); return true }; description = { _get = function(){ var hr,value = owner.$shellLink.GetDescription(256*2, 256); if( (hr)>=0/*SUCCEEDED*/) return value; } _set = function( value ){ owner.$shellLink.SetDescription(value); } }; arguments = { _get = function(){ var hr,value = owner.$shellLink.GetArguments(256*2, 256); if( (hr)>=0/*SUCCEEDED*/) return value; } _set = function( value ){ owner.$shellLink.SetArguments(value); } }; path = { _get = function(){ var hr,value = owner.$shellLink.GetPath(1024*2, 1024, {}, 0x2/*_SLGP_UNCPRIORITY*/); if( (hr)>=0/*SUCCEEDED*/) { value = #value ? value : owner[["(urlpath)"]]; if(value && ..string.indexOf(value," (x86)\") && !..io.exist(value) ){ value = ..string.replace(value,"@ (x86)\","\"); } return value; } } _set = function( target ){ owner[["(urlpath)"]] = null; if( #target ){ if( ..io.exist(target) ){ if( ..io.localpath(target) ) target = ..io.fullpath(target); if( !# owner.workDir ){ owner.$shellLink.SetWorkingDirectory( ..io.splitpath(target).dir ); } if( !# owner.description ){ var vesionInfo = ..fsys.version.getInfo( target ); if( vesionInfo ){ owner.description = vesionInfo.fileDescription; }; } } elseif( ..inet.url.is(target,0x0/*_URLIS_URL*/) ){ owner[["(urlpath)"]] = target; } } owner.$shellLink.SetPath(target); } }; filename = { _get = function(){ var path = owner.path; if( !#path ) return; if( ..inet.url.is(path,0x0/*_URLIS_URL*/ ) ){ var turl = ..inet.url.split(path); if( turl.path = "" || turl.path = "/" ) return ..string.concat( turl.host,owner.$defaultExt); return ..string.concat( ..io.splitpath( ..string.trimright(turl.path,"/") ).name || turl.host,owner.$defaultExt); } var vesionInfo = ..fsys.version.getInfo( path ); var productName = ..fsys.path.validName(vesionInfo.productName); if( (!vesionInfo) || (!#productName) ) return ..io.splitpath(path).name + owner.$defaultExt; return productName ++ owner.$defaultExt; } _set = function( value ){ if( value ){ if( !..string.endsWith(value,owner.$defaultExt,true) ) value = value + owner.$defaultExt; } owner[["filename"]] = value; } }; workDir = { _get = function(){ var hr,value = owner.$shellLink.GetWorkingDirectory(1024*2, 1024); if( (hr)>=0/*SUCCEEDED*/) return value; } _set = function( value ){ owner.$shellLink.SetWorkingDirectory(value); } }; hotkey = { _get = function(){ var hr,value = owner.$shellLink.GetHotkey(0); if( (hr)>=0/*SUCCEEDED*/) return value; } _set = function( value ){ owner.$shellLink.SetHotkey(value); } }; showCmd = { _get = function(){ var hr,value = owner.$shellLink.GetShowCmd(0); if( (hr)>=0/*SUCCEEDED*/) return value; } _set = function( value ){ owner.$shellLink.SetShowCmd(value); } }; pinToDesktop = function( pin,allUsers ){ var filename = owner.filename; if( !#filename ) error("未指定快捷方式存储文件名或目标路径",2); var commonPath = ..fsys.getSpecial( 0x19 /*_CSIDL_COMMON_DESKTOPDIRECTORY*/, filename ); var userPath = ..fsys.getSpecial( 0 /*_CSIDL_DESKTOP*/, filename ) if( pin ){ if( allUsers && commonPath ) { if(userPath) ..fsys.delete( userPath ); return owner.save( commonPath ); } else{ if(commonPath) ..fsys.delete( commonPath ); return owner.save( userPath ); } } else { if(commonPath) ..fsys.delete( commonPath ); if(userPath) ..fsys.delete( userPath ); return ! ..io.exist( commonPath ); } }; pinToPrograms = function( pin,sudir,allUsers ){ var filename = owner.filename; if( !#filename ) error("未指定快捷方式存储文件名或目标路径",2); var commonPath = ..fsys.getSpecial( 0x17 /*_CSIDL_COMMON_PROGRAMS*/,sudir ); var userPath = ..fsys.getSpecial( 0x2 /*_CSIDL_PROGRAMS*/,sudir ); var userDelPath = #sudir ? userPath : ..io.joinpath(userPath,filename) var commonDelPath = #sudir ? commonPath : ..io.joinpath(commonPath,filename) if( pin ){ if( allUsers ) { return owner.save( ..fsys.createDir( commonPath ) ); } else{ return owner.save( ..fsys.createDir( userPath ) ); } } else { ..fsys.delete( commonDelPath ); ..fsys.delete( userDelPath ); return ! ..io.exist( commonDelPath ); } }; pinToTaskbar = function(){};//@Deprecated pinToStartMenu = function(){};//@Deprecated free = function(){ if(owner.$shellLink){ ..com.Release(owner.$persistFile); ..com.Release(owner.$shellLink); owner.$persistFile = null; owner.$shellLink = null; if(owner.$uniformResourceLocator){ ..com.Release(owner.$uniformResourceLocator); owner.$uniformResourceLocator = null; } } } ) namespace lnk { enum = function(proc,dirClsId,...){ var subloop = dirClsId = (0x17 /*_CSIDL_COMMON_PROGRAMS*/) || ( dirClsId == 2 /*_CSIDL_PROGRAMS*/); var lnk = ..fsys.lnk(); var dir = type(dirClsId) == type.number ? ..fsys.getSpecial(dirClsId,...) : dirClsId; if(!dir) return; ..fsys.enum( dir , "*.lnk", function(dir,filename,fullpath){ if(filename){ var arguments; var target = getMsiTarget(fullpath); if(!target){ if( lnk.load( fullpath ) ){ target = lnk.path; arguments = lnk.arguments; } } if(target){ return proc( dir,..string.lower(filename),fullpath, target, arguments) } } },subloop ) lnk.free(); } searchLnk = function(pTarget,pLabel,dirClsId,...){ pTarget = pTarget ? ..string.lower(pTarget) pLabel = pLabel ? ..string.lower(pLabel); var dir = type(dirClsId) == type.number ? ..fsys.getSpecial(dirClsId,...) : dirClsId; if(!pLabel){ var path = ..io.joinpath(dir,pTarget); if(..io.exist(path)) return path; } var ret,retArguments; enum( function(dir,filename,fullpath,target,arguments){ var targetLow = ..string.lower(target); if(pTarget){ if( !..string.cmpMatch( ..io.splitpath(targetLow).file,pTarget ) ) && (!arguments || !..string.cmpMatch(arguments,pTarget) ) return; } if(pLabel){ if( !..string.cmpMatch( filename,pLabel ) ) return; } ret = target; retArguments = arguments; return false; },dirClsId,... ); return ret,retArguments; } search = function(pTarget,pLabel){ if( type(pTarget) == type.table ){ for(i=1;#pTarget;1){ var r = search(pTarget[i],pLabel); if( r ) return r; } return; } if(pTarget && !pLabel){ var path = ..fsys.searchFile(pTarget); if(path) return path; } var path,args = searchLnk( pTarget,pLabel, 0 /*_CSIDL_DESKTOP*/ ) if(path) return path,args; var path,args = searchLnk( pTarget,pLabel, 0x19 /*_CSIDL_COMMON_DESKTOPDIRECTORY*/ ) if(path) return path,args; var path,args = searchLnk( pTarget,pLabel, 2 /*_CSIDL_PROGRAMS*/ ) if(path) return path,args; var path,args = searchLnk( pTarget,pLabel, 0x17 /*_CSIDL_COMMON_PROGRAMS*/ ) if(path) return path,args; } searchInDesktop = function(pTarget,pLabel){ return searchLnk(pTarget,pLabel, 0 /*_CSIDL_DESKTOP*/ ) || searchLnk( pTarget,pLabel, 0x19 /*_CSIDL_COMMON_DESKTOPDIRECTORY*/ ) } var msi = ..raw.loadDll("msi.dll"); getMsiTarget = function(lnkPath){ var product = ..raw.buffer(78); var component = ..raw.buffer(78); if (0 == msi.MsiGetShortcutTargetW(lnkPath,product,null,component)){ var target = ..raw.buffer(0x208/*_MAX_PATH_U16*/); var cchBuf = {INT value = #target/2 } var r = msi.MsiGetComponentPathW(product,component,target,cchBuf); if (r == 3/*INSTALLSTATE_LOCAL*/ || r == 4/*INSTALLSTATE_SOURCE*/){ return ..string.fromUtf16(target,,-1); } } } getTarget = function(lnkPath){ var target = getMsiTarget(lnkPath); if(!target) { var lnk = ..fsys.lnk(); lnk.load(lnkPath); target = lnk.path; lnk.free(); } return target; } } /**intellisense(fsys.lnk) searchLnk("文件名或参数","快捷方式标题", 0 /*_CSIDL_DESKTOP*/) = 在桌面搜索快捷方式并返回路径\n参数@3可省略。\n成功返回启动路径与参数 searchLnk("文件名或参数","快捷方式标题", 2 /*_CSIDL_PROGRAMS*/) = 在开始菜单应用程序目录搜索快捷方式。\n成功返回启动路径与参数 search( = 查找文件或快捷方式。\n成功返回启动路径与参数 search(.("目标文件名或参数","快捷方式标题") = 全部参数可选,至少输入一个参数\n参数@1也可以是指定多个文件名的数组,\n搜索快捷方式的文件名与标题支持模式匹配或忽略大小写的文本比,\n直接搜索文件则必须精确匹配文件名。\n\n按下列顺序搜索文件:\n如果未指定标题则先调用 fsys.searchFile 在 EXE 目录及系统目录搜索,\n接着搜索桌面快捷方式、应用程序快捷方式 searchInDesktop( = 在桌面查找文件或快捷方式。\n成功返回启动路径与参数 searchInDesktop(.("目标文件名或参数","快捷方式标题") = 全部参数可选,至少输入一个参数\n参数@1也可以是指定多个文件名的数组。\n搜索快捷方式的文件名与标题支持模式匹配或忽略大小写的文本比较,\n直接搜索文件则必须精确匹配文件名 enum = @.enum( \n function(dir,filename,fullpath,target,arguments){ \n __/*return false 停止遍历*/ \n },0/*_CSIDL_DESKTOP*/\n); getMsiTarget(__/*lnk文件路径*/) = 获取MSI创建的 Advertised 快捷方式指向的实际目标路径 getTarget(__/*lnk文件路径*/) = 获取快捷方式指向的目标路径,\n支持Advertised Shortcut end intellisense**/ /**intellisense() !lnkfile.free() = 释放对象,\n释放对象以后不能再使用此对象 !lnkfile.resolve(.(hwndParent,flags) = 如果目标路径移动或丢失,\n查找符合的目标,可能显示查找对话框 !lnkfile.filepath = 快捷方式加载或保存成功的文件路径 !lnkfile.filename = 快捷方式默认文件名,可省略后缀名,\n未指定则取版本信息中的产品名或目标文件名 !lnkfile.description = 附加说明 !lnkfile.arguments = 参数 !lnkfile.path = 目标路径,设置该属性时:\n如果workDir为空则设workDir为目标路径所在目录\n如果description为空则设为版本信息中的文件描述 !lnkfile.workDir = 工作目录 !lnkfile.hotkey = 启动热键。\n16 位数值,低位字节为 虚拟键码 (virtual key code)。\n高位字节表示一个或多个修饰键的组合值:\n\n* _HOTKEYF_SHIFT (1): 表示 SHIFT 键。\n* _HOTKEYF_CONTROL (2): 表示 CTRL 键。\n* _HOTKEYF_ALT (4): 表示 ALT 键。\n* _HOTKEYF_EXT (8): 表示 扩展键。\n\n> 注意 _HOTKEYF_SHIFT,_HOTKEYF_ALT 与 _MOD_SHIFT,_MOD_ALT 的值刚好反过来。 !lnkfile.showCmd = 显示参数 !lnkfile.getIcon() = 返回图标文件路径,以及图标索引。 !lnkfile.setIcon(.(文件路径,图标索引) = 设置图标文件路径\n可以指定ico文件路径,也可指定EXE文件路径用于获取EXE图标\n图标索引可省略,默认为0 !lnkfile.load(__/*lnk文件路径*/) = 载入快捷方式,返回fsys.lnk对象自身 !lnkfile.load() = !lnkfile. !lnkfile.save(__/*lnk文件存储路径*/) = 保存快捷方式\n如果指定了filename或path属性,参数也可以指定存储目录 !lnkfile.pinToPrograms(.(true,"子目录路径") = 添加到开始菜单程序组\n可选指定子目录路径,参数@3如果为true则添加到所有用户程序组 !lnkfile.pinToPrograms(.(false,"子目录路径") = 自开始菜单程序组移除\n可选指定多个子目录参数\n如果指定了子目录则直接移除快捷方式所在父目录 !lnkfile.pinToDesktop(true) = 添加快捷方式到桌面\n,参数@2如果为true则添加到所有用户程序组 !lnkfile.pinToDesktop(false) = 自桌面移除快捷方式 ?fsys.lnk = !lnkfile. fsys.lnk() = 创建快捷方式\n!lnkfile. end intellisense**/