2011-10-12 14 views
13

निम्नलिखित VBScript कोड prefectly ठीक काम करता है:Marshal.GetActiveObject() सी # में MK_E_UNAVAILABLE अपवाद फेंकता

Dim App 
Set App = GetObject("","QuickTest.Application") 
App.Quit 

लेकिन जब मैंने उसे नीचे के रूप में सी # कोड में अनुवाद:

class Program 
{ 
    [STAThread] 
    static void Main(string[] args) 
    { 
     object qtApp = Marshal.GetActiveObject("QuickTest.Application"); 
     (qtApp as QuickTest.Application).Quit(); 
    } 
} 

मैं अपवाद :

प्रकार 'System.Runtime.InteropServices.COMException' की एक बिना क्रिया का अपवाद mscorlib.dll में हुआ

+०१२३५१६४१०६१

अतिरिक्त जानकारी: (HRESULT से अपवाद: 0x800401E3 (MK_E_UNAVAILABLE))

मुझे नहीं लगता कि समस्या आरओटी से संबंधित है, क्योंकि vbscript कोड काम करता है। तो सी # कोड के साथ क्या गलत है?

उत्तर

10

मार्शल.गेटएक्टिव ऑब्जेक्ट प्रोजेड का उपयोग करें, अपना प्रोगिड देखें, उदा। आप सड़ांध

using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 
using System.Text; 
using Microsoft.Win32; 
... 
class Program 
{ 
    private const int S_OK = 0x00000000; 

    [DllImport("ole32.dll")] 
    private static extern int GetRunningObjectTable(uint reserved, out IRunningObjectTable pprot); 

    [DllImport("ole32.dll")] 
    private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);  

    private static void OleCheck(string message, int result) 
    { 
     if (result != S_OK) 
      throw new COMException(message, result); 
    } 

    private static System.Collections.Generic.IEnumerable<IMoniker> EnumRunningObjects() 
    {   
     IRunningObjectTable objTbl; 
     OleCheck("GetRunningObjectTable failed", GetRunningObjectTable(0, out objTbl)); 
     IEnumMoniker enumMoniker; 
     IMoniker[] monikers = new IMoniker[1]; 
     objTbl.EnumRunning(out enumMoniker); 
     enumMoniker.Reset(); 
     while (enumMoniker.Next(1, monikers, IntPtr.Zero) == S_OK) 
     { 
      yield return monikers[0]; 
     } 
    } 

    private static bool TryGetCLSIDFromDisplayName(string displayName, out string clsid) 
    { 
     var bBracket = displayName.IndexOf("{"); 
     var eBracket = displayName.IndexOf("}"); 
     if ((bBracket > 0) && (eBracket > 0) && (eBracket > bBracket)) 
     { 
      clsid = displayName.Substring(bBracket, eBracket - bBracket + 1); 
      return true; 
     } 
     else 
     { 
      clsid = string.Empty; 
      return false; 
     } 
    } 

    private static string ReadSubKeyValue(string keyName, RegistryKey key) 
    { 
     var subKey = key.OpenSubKey(keyName); 
     if (subKey != null) 
     { 
      using(subKey) 
      { 
       var value = subKey.GetValue(""); 
       return value == null ? string.Empty : value.ToString(); 
      } 
     } 
     return string.Empty; 
    } 

    private static string GetMonikerString(IMoniker moniker) 
    { 
     IBindCtx ctx; 
     OleCheck("CreateBindCtx failed", CreateBindCtx(0, out ctx)); 
     var sb = new StringBuilder(); 
     string displayName; 
     moniker.GetDisplayName(ctx, null, out displayName); 
     sb.Append(displayName); 
     sb.Append('\t'); 
     string clsid; 
     if (TryGetCLSIDFromDisplayName(displayName, out clsid)) 
     { 
      var regClass = Registry.ClassesRoot.OpenSubKey("\\CLSID\\" + clsid); 
      if (regClass != null) 
      { 
       using(regClass) 
       { 
        sb.Append(regClass.GetValue("")); 
        sb.Append('\t'); 
        sb.Append(ReadSubKeyValue("ProgID", regClass)); 
        sb.Append('\t'); 
        sb.Append(ReadSubKeyValue("LocalServer32", regClass)); 
       } 
      } 
     } 
     return sb.ToString(); 
    } 

    [STAThread] 
    public static void Main(string[] args) 
    { 
     Console.WriteLine("DisplayName\tRegId\tProgId\tServer"); 
     foreach(var moniker in EnumRunningObjects()) 
     { 
      Console.WriteLine(GetMonikerString(moniker)); 
     } 
    } 
} 
+1

धन्यवाद! मैंने आरओटी में ऑब्जेक्ट्स को सूचीबद्ध करने के लिए अपना कोड इस्तेमाल किया, यह पता लगाने के लिए कि सूची में कोई भी क्विकटेस्ट संबंधित ऑब्जेक्ट नहीं है। लेकिन अजीब रूप से पर्याप्त, vbscript कोड अभी भी काम करता है! क्या vbscript का GetObject() फ़ंक्शन आरओटी को नहीं देखता है क्योंकि यह सी # समकक्ष करता है? – TomCaps

+1

http://msdn.microsoft.com/en-us/library/kdccchxa%28v=vs.85%29.aspx एमएसडीएन GetObject 1 टिप्पणी: "अगर पथनाम शून्य-लंबाई स्ट्रिंग (" ") है, GetObject रिटर्न निर्दिष्ट प्रकार का एक नया ऑब्जेक्ट उदाहरण। ", इसलिए आपका वीबीस्क्रिप्ट QuickTest.Aplication का नया उदाहरण बनाते हैं, और सी # में आपका कोड var qtApp = new QuickTest.Aplication() जैसा होना चाहिए; ... – MishaU

+0

मैंने सी # कोड बदल दिया var qtApp = new QuickTest.Aplication(); और यह काम करता है! आपका बहुत बहुत धन्यवाद! – TomCaps

29

में प्रदर्शन वस्तुओं के लिए इस कोड का उपयोग कर सकता है मैंने पाया कि ऊंचा विशेषाधिकारों (यानी व्यवस्थापक मोड) के साथ डिबगर/आईडीई चल इस समस्या पैदा कर सकता है जब प्रक्रिया आप का पता लगाने की कोशिश कर रहे ऊंचा विशेषाधिकारों के बिना चल रहा है ।

+2

मुझे मूर्खतापूर्ण, मैंने आपकी टिप्पणी नहीं देखी। इसलिए मैंने कोशिश की और कोशिश कर रहा था, जब तक कि यह मेरे प्रोग्राम को प्रतिबंधित कमांड प्रॉम्प्ट से चलाने का प्रयास करने के लिए नहीं आया। और यह काम किया। और फिर मैं अपने नए मिले ज्ञान को जोड़ने के लिए यहां आया, और मैंने आपकी टिप्पणी देखी। ओह अच्छा। चीयर्स! –

0

मुद्दा भी उठाया विशेषाधिकारों के साथ चलाकर नहीं शुरू किया जा सकता। ऐसा लगता है कि पिछले कुछ वर्षों में यह बदल गया है, इसलिए आईडीई या लक्ष्य कार्यक्रम को बिना किसी विशेषाधिकार के या उसके बिना चलाने के सभी क्रमिक प्रयासों का प्रयास करें।

अगस्त 2017 के रूप में, दृश्य स्टूडियो 2015 डिबगर के तहत आउटलुक 365 की चल उदाहरण प्राप्त करने के लिए, मैं MK_E_UNAVAILABLE त्रुटि से बचने के लिए निम्न करना था:

  • प्रारंभ आउटलुक के रूप में प्रशासक
  • प्रारंभ विजुअल स्टूडियो प्रशासक

डीबगर में चल रहा मेरा प्रोग्राम तब Outlook का चल रहा उदाहरण सफलतापूर्वक प्राप्त करने में सक्षम था।

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