Compilation 扫描COM引用以帮助生成无注册COM清单
我正在InstallShield 2015中以MSI安装程序的身份重新实施一个大型安装项目(它以前是InstallShield更旧版本的InstallScript安装程序)。我想做的许多改进之一是,通过使用清单文件和遵循无注册COM激活模式,允许以无注册的方式解析所有COM引用。我认为这不可能在所有情况下都实现,因为我们有一些MMC管理单元,据我所知,它们不能使用reg free COM,但我希望尽可能接近 挑战在于找出我需要创建的所有清单。我们提供数千个文件。我正在寻找一个实用程序,可以帮助扫描文件,以确定:Compilation 扫描COM引用以帮助生成无注册COM清单,compilation,com,windows-installer,installshield,dependency-management,Compilation,Com,Windows Installer,Installshield,Dependency Management,我正在InstallShield 2015中以MSI安装程序的身份重新实施一个大型安装项目(它以前是InstallShield更旧版本的InstallScript安装程序)。我想做的许多改进之一是,通过使用清单文件和遵循无注册COM激活模式,允许以无注册的方式解析所有COM引用。我认为这不可能在所有情况下都实现,因为我们有一些MMC管理单元,据我所知,它们不能使用reg free COM,但我希望尽可能接近 挑战在于找出我需要创建的所有清单。我们提供数千个文件。我正在寻找一个实用程序,可以帮助扫
如果已经有任何实用程序可能对此有所帮助,我想使用它,而不是自己编写。因此,我正在寻找任何关于自己写这篇文章的技巧,或者找到已经完成这篇文章的地方的技巧。在删除的答案的帮助下,我找到了一个类型库阅读类的C#源代码,我能够阅读类型库以获取CLSID值(如果尝试加载类型库失败,则跳过文件-只是尝试从每个可执行文件加载类型库)。然后,我对所有可执行文件进行了简单搜索,以查找那些CLSID值。我不确定结果是否完整,但它们至少看起来有点有效
GetDirCLSIDRefs
函数是顶级函数,它返回一个可执行文件名列表,并为每个文件返回一个关联文件列表,这些文件的类型库包含该文件引用的CLSID
Private Function GetDirCLSIDRefs(目录作为字符串,CLSIDs作为KeyValuePair(Guid的字符串)()作为KeyValuePair(字符串的字符串)()
Dim结果作为新列表(KeyValuePair(String,String())的)
Dim entries=New System.IO.DirectoryInfo(Directory.GetFileSystemInfos())
对于条目中的每个条目
如果条目类型为System.IO.FileInfo和ALSO_
(entry.Name.EndsWith(“.exe”)或_
entry.Name.EndsWith(“.dll”)或lse_
entry.Name.EndsWith(“.ocx”))然后
Dim refs=ScanForCLSIDs(entry.FullName,CLSIDs)
如果refs不是Nothing,并且refs.Length>0,则result.Add(新的KeyValuePair(字符串的,String())(entry.FullName,refs))
否则,如果条目类型为System.IO.DirectoryInfo,则
result.AddRange(GetDirCLSIDRefs(entry.FullName,CLSIDs))
如果结束
下一个
返回result.ToArray()
端函数
私有函数GetDirCLSIDs(目录作为字符串)作为KeyValuePair(Guid的字符串)()
Dim结果作为新列表(KeyValuePair的(Guid的,字符串的))
Dim entries=New System.IO.DirectoryInfo(Directory.GetFileSystemInfos())
对于条目中的每个条目
如果条目类型为System.IO.FileInfo和ALSO_
(entry.Name.EndsWith(“.exe”)或_
entry.Name.EndsWith(“.dll”)或lse_
entry.Name.EndsWith(“.ocx”))然后
对于GetCLSIDs中的每个clsid(entry.FullName)
添加(新的KeyValuePair(Guid、字符串)(clsid、entry.FullName))
下一个
否则,如果条目类型为System.IO.DirectoryInfo,则
result.AddRange(GetDirCLSIDs(entry.FullName))
如果结束
下一个
返回result.ToArray()
端函数
私有函数GetCLSIDs(文件名为字符串)作为Guid()
Dim tlb=TypeLibTypes.Interop.TypeLib.Load(文件名)
如果tlb.GetTypeLib()为Nothing,则返回{}
Dim结果作为新列表(Guid)
尝试
对于tlb.GetTypeInfoCount()-1,typeIndex为整数=0
使用attr=tlb.GetTypeInfo(typeIndex.GetTypeAttr()
如果(attr.wtypeblags和TypeLibTypes.Interop.TYPEFLAGS.TYPEFLAG\u FHIDDEN)=0_
AndAlso attr.typekind=TypeLibTypes.Interop.typekind.TKIND_COCLASS然后
结果.添加(属性Guid)
如果结束
终端使用
下一个
当ex.ErrorCode=&H80029C4A时,将ex捕获为System.Runtime.InteropServices.COMException
返回{}
结束尝试
返回result.ToArray()
端函数
私有函数ScanForCLSIDs(文件名为String,CLSIDFiles为KeyValuePair(Guid的字符串)()为String())
将内容设置为字节()
使用文件作为新System.IO.FileStream(文件名,IO.FileMode.Open,IO.FileAccess.Read,IO.FileShare.ReadWrite)
content=DirectCast(Array.CreateInstance(GetType(Byte)、CInt(file.Length))、Byte())
file.Read(content,0,CInt(file.Length))
终端使用
将结果变暗为新列表(字符串)
对于CLSIDFiles中的每个CLSIDFiles
如果FindBytes(content,CLSIDFile.Key.ToByteArray())>=0,则
如果不是result.Contains(CLSIDFile.Value),则是result.Add(CLSIDFile.Value)
如果结束
下一个
返回result.ToArray()
端函数
私有函数FindBytes(数据为Byte(),模式为Byte(),可选开始为Integer=0)为Int32
如果pattern.Length=0,则返回-1
如果data.Length=0,则返回0
暗淡的