private static bool IsLink(string shortcutFilename) { var pathOnly = Path.GetDirectoryName(shortcutFilename); var filenameOnly = Path.GetFileName(shortcutFilename); var shell = new Shell32.Shell(); var folder = shell.NameSpace(pathOnly); var folderItem = folder.ParseName(filenameOnly); return folderItem != null && folderItem.IsLink; }
我已经尝试将其转换为F#:
let private isLink filename = let pathOnly = Path.GetDirectoryName(filename) let filenameOnly = Path.GetFileName(filename) let shell = new Shell32.Shell() let folder = shell.NameSpace(pathOnly) let folderItem = folder.ParseName(filenameOnly) folderItem <> null && folderItem.IsLink
然而,它报告了一个let shell = new Shell32.Shell()行的错误,说新的不能用于接口类型.
我刚刚犯了一个愚蠢的语法错误,还是需要从F#访问COM所需的额外工作?
[ComImport] [Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")] [CoClass(typeof(ShellClass))] public interface Shell : IShellDispatch6 {}
IShellDispatch6是真正的接口类型,您还可以通过IShellDispatch5接口查看IShellDispatch.这是过去20年工作中的版本控制,COM接口定义是不可变的,因为更改它们几乎总是在运行时导致无法识别的硬崩溃.
[CoClass]属性是这个故事的重要属性,这就是C#编译器在[ComImport]接口类型上使用new的要求.告诉它通过创建Shell32.ShellClass实例的实例来创建对象并获取Shell接口. F#编译器没有做什么.
ShellClass是一个假类,它由类型库导入器自动生成. COM从不公开具体类,它使用基于超纯接口的编程范例.对象始终由对象工厂创建,CoCreateInstance()是其中的主力.本身就是一个方便的功能,真正的工作是通用IClassFactory interface,超纯风格.每个COM coclass都实现其CreateInstance()方法.
类型库导入器使ShellClass看起来像这样:
[ComImport] [TypeLibType(TypeLibTypeFlags.FCanCreate)] [ClassInterface(ClassInterfaceType.None)] [Guid("13709620-C279-11CE-A49E-444553540000")] public class ShellClass : IShellDispatch6,Shell { // Methods [MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(0x60040000)] public virtual extern void AddToRecent([In,MarshalAs(UnmanagedType.Struct)] object varFile,[In,Optional,MarshalAs(UnmanagedType.BStr)] string bstrCategory); // Etc,many more methods... }
大火和运动,不应该使用它们.唯一真正重要的是[Guid]属性,它提供了CoCreateInstance()所需的CLSID.它还需要接口声明提供的IID,接口的[Guid].
因此,F#中的解决方法是创建Shell32.ShellClass对象,就像C#编译器隐式执行一样.虽然从技术上讲,您可以将引用保留在ShellClass变量中,但您应该非常支持接口类型. COM方式,纯粹的方式,它避免了this kind of problem.最终它是完成工作的CLR,它在新的运算符实现中识别ShellClass类声明的[ClassInterface]属性. .NET中更明确的方法是使用Type.GetTypeFromCLSID()和Activator.CreateInstance(),当你只拥有coclass的Guid时很方便.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。