2009-12-07 19 views
13

मैं क्लिपबोर्ड में टेक्स्ट कॉपी के लिए निम्न कोड का उपयोग कर रहा:मैं कैसे "क्लिपबोर्ड नहीं खोल सकता: एक्सेस अस्वीकृत" त्रुटियों को कैसे ठीक कर सकता हूं?

Clipboard.Open; 
    try 
    Clipboard.AsText := GenerateClipboardText; 
    finally 
    Clipboard.Close; 
    end; 

मालूम होता है यादृच्छिक पर मैं मिलता है: त्रुटि "खुला क्लिपबोर्ड नहीं कर सकते प्रवेश निषेध"। मुझे लगता है कि ये त्रुटियां क्लिपबोर्ड को लॉक करने वाले अन्य एप्लिकेशन के कारण होती हैं, लेकिन मैं कभी भी अन्य अनुप्रयोगों के साथ कुछ भी नहीं कर रहा हूं जो ताले का कारण बनना चाहिए।

आश्चर्यजनक रूप से मेरे उपयोगकर्ता XP के साथ Vista और Windows 7 के साथ त्रुटियों की अधिक रिपोर्टिंग प्रतीत होते हैं।

क्या यह देखने का कोई तरीका है कि क्लिपबोर्ड को एक्सेस करने का प्रयास करने से पहले लॉक किया गया है या नहीं?

+0

कृपया डेल्फी के दस्तावेज़ से इस स्निपेट को नोट करें: "क्लिपबोर्ड। ओपन -> क्लिपबोर्ड खोलता है, अन्य अनुप्रयोगों को क्लिपबोर्ड बंद होने तक इसकी सामग्री को बदलने से रोकता है। क्लिपबोर्ड पर आइटमों की एक श्रृंखला जोड़ने से पहले कॉल करें। यह अन्य अनुप्रयोगों को रोकता है क्लिपबोर्ड को बंद होने तक ओवरराइट करने से। (क्लिपबोर्ड पर एक ही आइटम जोड़ते समय, ओपन कॉल करने की कोई आवश्यकता नहीं है।) " – Ampere

उत्तर

16

यह डेल्फी समस्या नहीं है। चूंकि क्लिपबोर्ड को किसी भी पल को लॉक किया जा सकता है, भले ही आप चेक करते हैं, अगर क्लिपबोर्ड वर्तमान में लॉक नहीं है, तो यह चेक के बाद सीधे लॉक हो सकता है।

  1. डेल्फी क्लिपबोर्ड वर्ग का उपयोग न करें:

    आप यहाँ दो संभावनाएं है। इसके बजाय कच्चे एपीआई फ़ंक्शंस का उपयोग करें, जहां आपके पास संभावित त्रुटि स्थितियों पर थोड़ा अधिक बढ़िया नियंत्रण है।

  2. अपवाद हैंडलर जोड़कर विफल होने के लिए अपने कोड की अपेक्षा करें। फिर कुछ पुनः प्रयास कोड जोड़ें, यानी अपनी खुद की त्रुटि फेंकने से पहले, पाठ को तीन बार सेट करने के लिए पुनः प्रयास करें, शायद घातीय बैकऑफ के साथ।

मैं दूसरे समाधान की सिफारिश करता हूं, क्योंकि यह अधिक डेल्फी जैसा दृष्टिकोण होगा और अंत में क्लीनर कोड होगा।

while not Success do 
try 
    //Set the clipboard 
    Success := True; 
except 
    on Exception do 
    begin 
    Inc(RetryCount); 
    if RetryCount < 3 then 
     Sleep(RetryCount * 100) 
    else 
     raise MyException.Create('Cannot set clipboard'); 
    end; 
end; 
+3

यह Win32 समस्या नहीं है - यह एक साधारण तथ्य है जब समवर्ती सिस्टम के लिए प्रोग्रामिंग। – mghie

1

कुछ की जांच करने का कोई तरीका नहीं है और फिर परिणाम के आधार पर कुछ और उम्मीद है कि यह असफल नहीं हो सकता है, क्योंकि जब तक कि जांच और कार्रवाई एक परमाणु संचालन न हो, हमेशा संभावना है कि एक और प्रक्रिया या थ्रेड समानांतर में समान होता है।

यह धारण करता है कि क्या आप क्लिपबोर्ड खोलने, फ़ाइल खोलने, निर्देशिका बनाने या हटाने का प्रयास करते हैं - आपको बस इसे करने की कोशिश करनी चाहिए, शायद लूप में कई बार, और गलतियों को गलती से संभाल लें।

0

GetClipboardOwner को जांचने का प्रयास करें, अगर यह शून्य नहीं है और आपका आवेदन नहीं है। हैंडल, आप इसकी सामग्री को संशोधित करने के लिए नहीं खोल सकते हैं।
और यहां तक ​​कि यह जाने के लिए अच्छा लगता है, यह वास्तव में ऐसा नहीं हो सकता है जब आप वास्तव में ऐसा करते हैं।
तो जब तक आप इसे प्राप्त न करें या अच्छी तरह से छोड़ दें (उदाहरण के लिए उपयोगकर्ता को सूचित करें) तब तक एक लूप को छोड़कर एक प्रयास जोड़ें।

1

सबसे पहले कृपया ध्यान दें कि यह संभवतः आपके आवेदन में कोई समस्या नहीं है। अन्य अनुप्रयोगों ने क्लिपबोर्ड को बंद कर दिया या अधिसूचना श्रृंखला को गड़बड़ कर दिया और अब आपका एप्लिकेशन इसे एक्सेस करने में विफल रहता है। जब मुझे इस तरह की समस्याएं होती हैं तो मैं कंप्यूटर को पुनरारंभ करता हूं और वे जादुई रूप से दूर जाते हैं ... अच्छा ... कम से कम जब तक मैं उस समस्या को फिर से चलाता हूं जो समस्या उत्पन्न करता है।

यह कोड (डेल्फी में चेक नहीं किया गया) आपकी मदद कर सकता है। यह समस्या को ठीक नहीं करेगा अधिसूचना श्रृंखला टूट गई है (पीसी रीस्टार्ट को छोड़कर कुछ भी इसे ठीक नहीं करेगा) लेकिन अगर कोई एप्लिकेशन क्लिपबोर्ड को लॉक कर रहा है तो यह समस्या ठीक कर देगा।MaxRetries बढ़ाएँ अगर वह परेशान आवेदन क्लिपबोर्ड एक बहुत लंबा समय के लिए बंद कर दिया (सेकंड) रखता है:

procedure Str2Clipboard(CONST Str: string; iDelayMs: integer); 
CONST 
    MaxRetries= 5; 
VAR RetryCount: Integer; 
begin 
RetryCount:= 0; 
for RetryCount:= 1 to MaxRetries DO 
    TRY 
    inc(RetryCount); 
    Clipboard.AsText:= Str; 
    Break; 
    EXCEPT 
    on Exception DO 
     if RetryCount = MaxRetries 
     then RAISE Exception.Create('Cannot set clipboard') 
     else Sleep(iDelayMs) 
    END; 
end; 

इसके अलावा, यह 'बढ़ाने' ड्रॉप और यह एक समारोह में बदल जाएंगे और इसका इस्तेमाल करने के लिए एक अच्छा विचार हो सकता इस तरह:

if not Str2Clipboard 
then Log.AddMsg('Dear user, other applications are blocking the clipboard. We have tried. We really did. But it didn''t work. Try again in a few seconds.'); 
+0

आपकी नींद काफी लंबी नहीं है। 15ms कुछ भी करने वाला नहीं है। 5x15ms के बाद, जो कुछ भी क्लिपबोर्ड खुला था, वह अभी भी है। –

+0

आप सही हो सकते हैं लेकिन दूसरी ओर यदि आप लंबी देरी का उपयोग करते हैं तो आपके पास क्लिपबोर्ड उपयोग में आने के कारण एप्लिकेशन को कुछ सेकंड के लिए लटका दिया जा सकता है। शायद प्रत्येक प्रोग्रामर को यह तय करना चाहिए कि "फ्रीज" कितना स्वीकार्य है। – Ampere

+0

यहां तक ​​कि बेहतर: देरी को प्रक्रिया के लिए पैरामीटर के रूप में भी इस्तेमाल किया जा सकता है। --- मैंने अभी कोड अपडेट किया है। – Ampere

8

अजीब मेरे उपयोगकर्ताओं के साथ त्रुटियों की अधिक रिपोर्टिंग होने लगते हैं विस्टा और विंडोज 7 से XP

साथ

यह क्लिपबोर्ड दर्शक अधिसूचना के साथ Vista/Win7 सौदे के साथ कैसे करना पड़ सकता है। हालांकि वे अभी भी एक्सपी "क्लिपबोर्ड व्यूअर चेन" का समर्थन करते हैं, जो एक अधिसूचना संदेश भेजता है जिसे बदले में प्रत्येक श्रोता को फिर से भेजा जाना चाहिए (और यदि कोई ऐप ऐसा करने में विफल रहता है, तो अन्य ऐप्स अधिसूचित नहीं किए जाते हैं)। Vista से शुरू होने पर, ऐप्स को सीधे सूचित किया जाता है। और क्लिपबोर्ड को एक बार में एक्सेस करने की कोशिश करने से उन्हें रखने के लिए कुछ भी नहीं है।

एनालॉजी: मेरे 3 बच्चे हैं। मेरे पास एक केक है एक्सपी नियमों के साथ, मैं सबसे पुराने बच्चे को कुछ केक रखने के लिए कहता हूं, फिर अगले सबसे पुराने बच्चे को टुकड़ा करने के लिए कहें। उसे उसका टुकड़ा मिलता है, अपने भाई से कहता है, वह उसे प्राप्त करता है, और अपने भाई को बताता है, जो उसे प्राप्त करता है, और सबकुछ व्यवस्थित तरीके से मिलता है।
समस्या: मध्य बच्चा अपने कमरे में केक लेता है, सबसे कम उम्र में नहीं बताता है, और सबसे कम उम्र के लोगों को याद आती है।

Vista/Windows7 के साथ, वह सिस्टम अभी भी मौजूद है। लेकिन जैसे ही केक रसोईघर में आता है, नए ऐप्स तुरंत मेरे द्वारा अधिसूचित होने का अनुरोध कर सकते हैं। मैं चिल्लाता हूं "केक तैयार है!" और वे सभी एक ही समय में दिखाई देते हैं और कुछ को पकड़ने की कोशिश करते हैं। लेकिन केवल एक ही चाकू की सेवा है, इसलिए उन्हें चाकू तक पहुंचने, इसे पाने में नाकाम रहने और अगले अवसर की प्रतीक्षा करनी है।

0

मुझे लगता है कि आप Win 8 या उच्चतर पर अपना ऐप चला रहे हैं।

बस अपनी ऐप .exe फ़ाइल पर राइट-क्लिक करें, संगतता टैब पर जाएं और Windows XP या निम्न संस्करणों पर संगतता मोड बदलें। यह काम करेगा, गारंटी!

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