2016-05-10 13 views
5

मैं निम्नलिखित सी # विधि है:,सी # कोड को कैसे परिवर्तित करें जो शैल COM से 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() लाइन के लिए एक त्रुटि रिपोर्ट कह रही है कि new इंटरफेस पर नहीं किया जा सकता:

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; 
} 

मैं के रूप में एफ # करने के लिए इस परिवर्तित करने की कोशिश की है प्रकार के।

क्या मैंने अभी एक मूर्ख वाक्य रचनात्मक गलती की है, या क्या एफ # से COM तक पहुंचने के लिए अतिरिक्त काम की आवश्यकता है?

+1

मैंने सोचा कि मैं एक उत्तर के लिए एक लोकप्रिय खोज इंजन को दोबारा जांच दूंगा। "एफ # कॉम शेल 32" खोजा गया और यह इस सवाल के साथ शीर्ष परिणाम के रूप में आया! !! मान लीजिए यह एक सामान्य एफ # उपयोग-मामला नहीं है :) –

+4

एफ # कंपाइलर शायद [CoClass] विशेषता लुकअप सुविधा खो रहा है। इंटरऑप प्रकारों को एम्बेड करने का समर्थन नहीं करेगा। कामकाज 'नए शैल 32 का उपयोग करना है।Shell32Class() 'या बस इसे सी # कक्षा पुस्तकालय में लिखें और इसके लिए एक संदर्भ जोड़ें, मुझे संदेह है कि हर कोई ऐसा करता है। –

+0

@ हंसपैसेंट, धन्यवाद, जिसने मुझे सही दिशा में इंगित किया। 'शैल = new Shell32.ShellClass()' को समस्या को ठीक करने के लिए लाइन को बदलना और यह सब अपेक्षित के रूप में कार्य करता है। अब काम करने के लिए * क्यों * यह काम करता है, क्योंकि मैं "ओह, यह तय करना चाहता हूं, अब आगे बढ़ने के लिए" दृष्टिकोण नहीं लेना चाहता; मुझे जानने की जरूरत है! :) –

उत्तर

9

मुझे एफ # कंपाइलर के बारे में पर्याप्त जानकारी नहीं है लेकिन आपकी टिप्पणियां इसे स्पष्ट बनाती हैं। सी # और वीबीएनईटी कंपाइलर्स में COM अंतर्निहित के लिए स्पष्ट समर्थन की उचित मात्रा है। ध्यान दें कि आपके बयान एक अंतरफलक प्रकार पर new ऑपरेटर का उपयोग करता है, इंटरॉप पुस्तकालय में Shell32.Shell इस तरह दिखता है:

[ComImport] 
[Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")] 
[CoClass(typeof(ShellClass))] 
public interface Shell : IShellDispatch6 {} 

IShellDispatch6 असली इंटरफ़ेस प्रकार, आप भी IShellDispatch5 इंटरफेस के माध्यम से IShellDispatch देख सकते है। यह काम पर पिछले 20 वर्षों में संस्करण है, COM इंटरफ़ेस परिभाषाएं अपरिवर्तनीय हैं क्योंकि उन्हें बदलने से लगभग हमेशा रनटाइम पर एक अवांछनीय हार्ड क्रैश होता है।

इस कहानी के लिए [CoClass] विशेषता महत्वपूर्ण है, यही कारण है कि सी # कंपाइलर आपको [ComImport] इंटरफ़ेस प्रकार पर new का उपयोग करने की तलाश में है। इसे Shell32.ShellClass इंस्टेंस का उदाहरण बनाकर ऑब्जेक्ट बनाने के लिए कहता है और शैल इंटरफ़ेस प्राप्त करता है। एफ # कंपाइलर क्या नहीं करता है।

ShellClassनकली वर्ग है, यह प्रकार लाइब्रेरी आयातक द्वारा स्वतः उत्पन्न होता है। COM कभी कंक्रीट कक्षाओं का खुलासा नहीं करता है, यह एक हाइपर-शुद्ध इंटरफ़ेस-आधारित प्रोग्रामिंग प्रतिमान का उपयोग करता है। ऑब्जेक्ट्स हमेशा ऑब्जेक्ट फैक्ट्री द्वारा बनाए जाते हैं, CoCreateInstance() इसके लिए वर्कहोर है। स्वयं एक सुविधा समारोह, असली काम सार्वभौमिक IClassFactory interface, हाइपर-शुद्ध शैली द्वारा किया जाता है। प्रत्येक COM coclass इसकी CreateInstance() विधि लागू करता है। ,

[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... 
} 

आग और आंदोलन की बहुत सारे यह से कोई भी कभी भी इस्तेमाल किया जाना चाहिए:

प्रकार लायब्रेरी आयातक बना देता है ShellClass इस तरह दिखेगा। केवल एक चीज है कि वास्तव में मायने रखता है [Guid] विशेषता है, जो सीएलएसआईडी प्रदान करता है जो CoCreateInstance() की आवश्यकता है। इंटरफ़ेस घोषणा द्वारा प्रदान किए गए इंटरफ़ेस के आईआईडी, [गाइड] की भी आवश्यकता है।

तो F # में वर्कअराउंड Shell32.ShellClass ऑब्जेक्ट बनाने के लिए है, जैसे सी # कंपाइलर निहित रूप से करता है। तकनीकी रूप से आप संदर्भ को शैल क्लास चर में रख सकते हैं, आपको इसके बजाय इंटरफ़ेस प्रकार का दृढ़ता से समर्थन करना चाहिए। COM रास्ता, शुद्ध तरीका, यह this kind of problem से बचाता है। आखिरकार यह सीएलआर है जो काम पूरा करता है, यह new ऑपरेटर कार्यान्वयन में शैल क्लास कक्षा घोषणा पर [क्लासइंटरफेस] विशेषता को पहचानता है। .NET में अधिक स्पष्ट तरीका टाइप.GetTypeFromCLSID() और Activator.CreateInstance() का उपयोग करना है, जब आपके पास केवल कोक्लस का ग्रिड होता है।

+3

इसके पीछे मशीनरी में दिलचस्पी रखने वालों के लिए, जॉन स्कीट का ब्लॉग पोस्ट, [सी # कंपाइलर को मूर्ख बनाने के लिए फोकिंग कॉम] (https://codeblog.jonskeet.uk/2009/07/07/faking-com-to-fool-the -सी-कंपाइलर /) इस विषय पर एक अलग परिप्रेक्ष्य से चर्चा करता है। – Brian

संबंधित मुद्दे