आज का Windows शेल इंटीग्रेशन ── कॉन्टेक्स्ट मेनू, फ़ाइल असोसिएशन, और Windows 11 में क्या बदला
· Go Komura · Windows, शेल एक्सटेंशन, कॉन्टेक्स्ट मेनू, फ़ाइल असोसिएशन, COM, Windows 11, फ़ाइल एक्सप्लोरर, MSIX, Windows विकास
मुझसे सलाह माँगी गई: «हमने PC Windows 11 से बदल दिए, और सालों पहले आपके बनाए ऐप का कॉन्टेक्स्ट मेनू गायब हो गया»। और ध्यान से सुनने पर वह गायब नहीं हुआ था। फ़ाइल पर राइट-क्लिक करें, मेनू के नीचे “अधिक विकल्प दिखाएँ” चुनें, और परिचित मेनू वैसा ही आता है जैसा हमेशा आता था। यानी इन-हाउस ऐप के मेनू आइटम एक क्लिक और अंदर छिप गए। मैदान से «एक क्लिक ज़्यादा» और «आइटम नहीं मिलता, ऐसी पूछताछ बढ़ गई» सुनाई देता है।
यह न तो खराबी है न गलत कॉन्फ़िगरेशन; यह Windows 11 का डिज़ाइन परिवर्तन है। फ़ाइल एक्सप्लोरर का कॉन्टेक्स्ट मेनू पुराने और नए की दो-परत संरचना बन गया, और नए मेनू पर आइटम रखने की शर्तें पहले से पूरी तरह अलग चीज़ हो गईं।
इधर नीचे की फ़ाइल-असोसिएशन और शेल-एक्सटेंशन मशीनरी अभी भी COM और रजिस्ट्री की पुरानी दुनिया है। एक्सटेंशन कुंजी ProgID की ओर इशारा करती है, ProgID का verb कमांड लाइन रखता है, और ज़्यादा उलझा एक्सटेंशन एक्सप्लोरर में लोड होने वाले इन-प्रोसेस COM सर्वर (DLL) के रूप में चलता है — यह संरचना बीस साल से अधिक नहीं बदली। अगर आप न बदली हुई नींव और Windows 11 द्वारा दो भागों में बाँटे गए मेनू दोनों न जानें, तो «मेनू नहीं दिखता», «छिप गया» या «दो बार दिखता है» अलग नहीं कर सकते।
यह लेख छोटे-मझोले उद्यमों के IT कर्मचारियों और व्यावसायिक ऐप सँभालने वाले Windows डेवलपरों के लिए है। यह एक ही चित्र में फ़ाइल असोसिएशन की तीन-परत संरचना, क्लासिक शेल एक्सटेंशन की सावधानियाँ, Windows 11 नए कॉन्टेक्स्ट मेनू को निशाना बनाना, और इंस्टॉलर पंजीकरण, सफ़ाई तथा समस्या-निवारण जोड़ता है।
1. निष्कर्ष पहले
- कॉन्टेक्स्ट मेनू और फ़ाइल असोसिएशन की नींव तीन-परत रजिस्ट्री संरचना «एक्सटेंशन कुंजी → ProgID → verb» है। एक्सटेंशन कुंजी ProgID की ओर पॉइंटर है, ProgID सार है, और उसके नीचे
shell\<verb>\commandकमांड लाइन रखता है।1 - HKEY_CLASSES_ROOT (HKCR) स्वतंत्र हाइव नहीं है; यह HKLM\Software\Classes और HKCU\Software\Classes का मर्ज्ड व्यू है। सभी-उपयोगकर्ता पंजीकरण HKLM पर लिखें, प्रति-उपयोगकर्ता HKCU पर, और HKCR को केवल-पढ़ने योग्य मानें।2
- डिफ़ॉल्ट ऐप (डबल-क्लिक पर खुलने वाला) उपयोगकर्ता द्वारा चुना जाने के लिए डिज़ाइन है, और प्रोग्राम उसे चुरा नहीं सकता। OS उपयोगकर्ता की पसंद की रक्षा करता है; इंस्टॉलर उम्मीदवार के रूप में पंजीकृत कर सकता है।3
- क्लासिक शेल एक्सटेंशन एक्सप्लोरर में लोड होने वाला इन-प्रोसेस COM DLL है। एक्सटेंशन में क्रैश या देरी पूरे एक्सप्लोरर (और शेल इस्तेमाल करने वाले अन्य ऐप) तक फैलती है; 64-बिट वातावरण को 64-बिट DLL चाहिए; मैनेज्ड-कोड इम्प्लीमेंटेशन असमर्थित है।45
- Windows 11 पर कॉन्टेक्स्ट मेनू दो भागों में बँट गया। नए मेनू पर वही कमांड दिखती हैं जो IExplorerCommand प्लस पैकेज पहचान से पंजीकृत हैं; क्लासिक IContextMenu एक्सटेंशन «अधिक विकल्प दिखाएँ» (Shift+F10) वाले पुराने मेनू पर चले जाते हैं।67
- नए मेनू पर कस्टम कमांड रखने का आधिकारिक मार्ग IExplorerCommand लागू करने वाले नेटिव DLL को MSIX मैनिफ़ेस्ट (desktop4:FileExplorerContextMenus) में पंजीकृत करना है। जो ऐप MSIX नहीं बन सकता उसे अकेले पहचान sparse package (बाहरी लोकेशन वाला MSIX) से दी जा सकती है।78
- अगर बस «इस ऐप से खोलें» चाहिए, तो असोसिएशन और स्टैटिक verb अभी भी काफी हैं। शेल-एक्सटेंशन DLL की ज़रूरत नहीं, और Microsoft स्वयं साफ़ कहती है «आवश्यकता पूरी करने वाला सबसे सरल तरीका चुनें (स्टैटिक verb)»।9
- पंजीकरण या बदलाव के बाद SHChangeNotify(SHCNE_ASSOCCHANGED) से सूचित करें; अनइंस्टॉल पर ProgID हटाएँ पर एक्सटेंशन कुंजी का डिफ़ॉल्ट मान न हटाएँ — यही आधिकारिक मार्गदर्शन है। शेल इंटीग्रेशन में सफ़ाई का डिज़ाइन भी शामिल है।110
एक वाक्य में: असोसिएशन और verb की दुनिया नहीं बदली; केवल मेनू कैसे दिखता है, Windows 11 पर दो भागों में बँट गया। नीचे हम नींव से ऊपर चलते हैं।
2. फ़ाइल असोसिएशन कैसे काम करता है ── तीन-परत संरचना एक्सटेंशन कुंजी → ProgID → verb
2.1. एक उदाहरण से तीन-परत संरचना पढ़ना
किसी दिए एक्सटेंशन की फ़ाइल पर डबल-क्लिक करने पर क्या होता है, तीन परतों की रजिस्ट्री कुंजियाँ तय करती हैं।1
HKEY_CLASSES_ROOT
.kmrpt ← (1) एक्सटेंशन कुंजी
(Default) = KomuraSoft.Report.1 ← केवल ProgID नाम देने वाला पॉइंटर
OpenWithProgids
KomuraSoft.Report.1 ← «इससे खोलें» का उम्मीदवार
KomuraSoft.Report.1 ← (2) ProgID (असोसिएशन का सार)
(Default) = Komura Report document
DefaultIcon
(Default) = "C:\Program Files\KomuraSoft\Report.exe",0
shell ← (3) verb की सूची
open
command
(Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
- (1) एक्सटेंशन कुंजी (
.kmrpt) केवल डिफ़ॉल्ट मान के रूप में ProgID नाम की ओर इशारा करती है। यहाँ सीधे कमांड लिखना गलती है। - (2) ProgID (
KomuraSoft.Report.1) असोसिएशन का सार है; इसमें प्रदर्शन नाम, आइकन और verb सूची रहती है। - (3) verb «खोलें» या «प्रिंट» जैसी क्रिया है, और
shell\open\commandका डिफ़ॉल्ट मान वास्तव में लॉन्च होने वाली कमांड लाइन है।
इसी अलगाव के कारण आप कई एक्सटेंशन (उदाहरण .kmrpt और .kmrpt-file) एक ही ProgID की ओर रख सकते हैं, या ऐप अपग्रेड पर ProgID बदल सकते हैं।
flowchart TB
accTitle: फ़ाइल असोसिएशन की तीन-परत संरचना
accDescr: एक्सटेंशन कुंजी एक पॉइंटर है जिसका डिफ़ॉल्ट मान ProgID नाम देता है; ProgID सार है जो प्रदर्शन नाम, आइकन और verb सूची रखता है; और verb के नीचे command का डिफ़ॉल्ट मान वास्तव में लॉन्च होने वाली कमांड लाइन है
ext["एक्सटेंशन कुंजी .kmrpt"] -->|डिफ़ॉल्ट में ProgID नाम| pid["ProgID KomuraSoft.Report.1"]
pid --> vb["verb (shell के नीचे open आदि)"]
vb --> cmd["command का डिफ़ॉल्ट मान"]
cmd --> exe["Report.exe लॉन्च होता है"]
pid -.-> attr["प्रदर्शन नाम और DefaultIcon भी रखता है"]
चित्र 1: एक्सटेंशन कुंजी पॉइंटर है, ProgID सार है, और verb की command वास्तव में लॉन्च होने वाली कमांड लाइन है।
2.2. HKCR «मर्ज्ड व्यू» है ── कहाँ लिखें, अर्थ बदल जाता है
ऊपर का उदाहरण HKEY_CLASSES_ROOT (HKCR) के नीचे दिखाया गया है, पर HKCR भौतिक संग्रह स्थान नहीं है; यह HKLM\Software\Classes और HKCU\Software\Classes का मर्ज्ड व्यू है। दोनों में एक ही कुंजी हो तो HKCU पक्ष जीतता है।2
flowchart TB
accTitle: HKCR मर्ज्ड व्यू है
accDescr: HKCR HKLM और HKCU Classes एक के ऊपर एक हैं; दोनों में एक ही कुंजी हो तो HKCU जीतता है; पंजीकरण HKLM या HKCU पर स्पष्ट लिखें और HKCR को केवल-पढ़ने योग्य मानें
hklm["HKLM\\Software\\Classes (सभी उपयोगकर्ता)"] --> hkcr["HKCR (मर्ज्ड व्यू)"]
hkcu["HKCU\\Software\\Classes (प्रति उपयोगकर्ता)"] --> hkcr
hkcu -.-> win["एक ही कुंजी हो तो HKCU जीतता है"]
hkcr -.-> ro["केवल-पढ़ने योग्य मानें (पुष्टि के लिए)"]
चित्र 2: HKCR HKLM और HKCU Classes के साथ रखने का रूप है; लिखने का गंतव्य हमेशा एक पक्ष नामें।
| लिखने का गंतव्य | अर्थ | आवश्यक अधिकार |
|---|---|---|
HKLM\Software\Classes |
सभी उपयोगकर्ताओं के लिए साझा पंजीकरण | व्यवस्थापक |
HKCU\Software\Classes |
केवल उस उपयोगकर्ता का पंजीकरण | कोई नहीं |
सीधे HKCR पर लिखना |
मौजूदा कुंजी पहले से कहाँ है, उसी के अनुसार वितरित | निर्भर |
व्यवहार में सुरक्षित विभाजन है पंजीकरण हमेशा HKLM या HKCU पर स्पष्ट लिखें, और HKCR को पुष्टि के लिए केवल-पढ़ने योग्य मानें। WOW64 रजिस्ट्री रीडायरेक्शन से संबंध भी सुलझाना चाहिए। HKLM\Software\Classes के ठीक नीचे एक्सटेंशन कुंजी और ProgID जैसे असोसिएशन डेटा Windows 7 से 32-बिट और 64-बिट रजिस्ट्री व्यू के बीच साझा हैं, इसलिए 32-बिट इंस्टॉलर लिखने पर Wow6432Node की ओर नहीं भागता। दूसरी ओर Classes\CLSID जैसी कुछ COM-पंजीकरण उपकुंजियाँ रीडायरेक्ट होती हैं, और शेल एक्सटेंशन (इन-प्रोसेस COM) पंजीकृत करते समय 32-बिट / 64-बिट लेखन विभाजन मायने रखता है। विवरण «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the "The Value I Wrote Isn’t There" Problem» में है।
2.3. ऐप पक्ष पर पंजीकरण ── App Paths, Applications, RegisteredApplications
फ़ाइल पक्ष (एक्सटेंशन और ProgID) के साथ जोड़कर ऐप पक्ष पर भी तीन तरह के पंजीकरण हैं।11
- App Paths (
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): पंजीकरण जिससेShellExecuteExकेवल निष्पादन योग्य फ़ाइल नाम से लॉन्च कर सके। Microsoft इसकी सिफ़ारिश करती है क्योंकि PATH पर्यावरण चर को गंदा नहीं करना पड़ता। - Applications (
HKCR\Applications\<app.exe>): «इससे खोलें» के तहत कोई भी फ़ाइल सौंपे जाने पर डिफ़ॉल्ट खोलने का तरीका, और ऐप का प्रदर्शन नाम (FriendlyAppName) परिभाषित करता है। - RegisteredApplications + Capabilities: ऐप जिन एक्सटेंशन और MIME प्रकार सँभाल सकता है उन्हें घोषित करता है, और वही पंजीकरण Windows Default apps सेटिंग पेज पर उम्मीदवार बनाता है।
«हमारा ऐप Default apps सूची में नहीं दिखता» जैसी अधिकांश सलाह वे मामले हैं जहाँ ProgID पंजीकृत हुआ और यह Capabilities पंजीकरण छूट गया।
flowchart TB
accTitle: ऐप पक्ष पर तीन तरह के पंजीकरण
accDescr: ऐप-पक्ष पंजीकरण तीन तरह का है ── App Paths, Applications और RegisteredApplications ── क्रमशः केवल फ़ाइल नाम से लॉन्च, इससे खोलें के तहत डिफ़ॉल्ट तरीका, और Default apps पेज पर दिखना
app["ऐप-पक्ष पंजीकरण"] --> ap["App Paths"]
app --> apps["Applications"]
app --> ra["RegisteredApplications"]
ap --> r1["केवल फ़ाइल नाम से लॉन्च"]
apps --> r2["इससे खोलें का डिफ़ॉल्ट"]
ra --> r3["Default apps पेज पर दिखता है"]
r3 -.-> cap["Capabilities घोषणा चाहिए"]
चित्र 3: ऐप-पक्ष पंजीकरण तीन तरह का है, और Default apps उम्मीदवार बनने के लिए Capabilities पंजीकरण चाहिए।
2.4. डिफ़ॉल्ट ऐप उपयोगकर्ता का है ── UserChoice सुरक्षा
एक्सटेंशन कुंजी के डिफ़ॉल्ट मान के रूप में ProgID लिखना अकेले उसे डिफ़ॉल्ट ऐप नहीं बनाता। उपयोगकर्ता द्वारा «इससे खोलें» आदि के तहत स्पष्ट चुनाव का परिणाम HKCU\...\Explorer\FileExts\<extension>\UserChoice में रहता है, और असोसिएशन समाधान उस पक्ष को प्राथमिकता देता है।
और महत्वपूर्ण बात यह है कि Windows प्रोग्रामेटिक रूप से डिफ़ॉल्ट ऐप बदलने का समर्थन नहीं करता। डिफ़ॉल्ट-ऐप सेटिंग्स उपयोगकर्ता द्वारा सिस्टम Settings UI से करने के लिए डिज़ाइन हैं; UserChoice डेटा अस्पष्ट है, और फ़िल्टर ड्राइवर (UCPD.sys) ऐप्स से लेखन रोकता है। प्रबंधित वातावरण में Group Policy / MDM नीति आधिकारिक साधन है।3
SetUserFTA जैसे उपकरण, जो «हैश की नकल करके फिर लिखते हैं», इस्तेमाल हुए हैं — यही सुरक्षा का दूसरा पहलू है। इन-हाउस ऐप के इंस्टॉलर में डिफ़ॉल्ट चुराना नहीं, बल्कि ये तीन रखने चाहिए: (क) ProgID और verb का सही पंजीकरण, (ख) खुद को OpenWithProgIds में जोड़ना, और (ग) ज़रूरत हो तो Settings पेज पर ले जाना।
flowchart TB
accTitle: डिफ़ॉल्ट-ऐप समाधान और UserChoice सुरक्षा
accDescr: उपयोगकर्ता के स्पष्ट चुनाव का परिणाम UserChoice में रहता है और असोसिएशन समाधान में प्राथमिकता पाता है; UCPD.sys ऐप्स से फिर-लेखन रोकता है, इसलिए इंस्टॉलर उम्मीदवार के रूप में पंजीकृत कर Settings पेज पर ले जा सकता है
uc["UserChoice (उपयोगकर्ता की पसंद)"] -->|प्राथमिक| res["असोसिएशन समाधान"]
ext["एक्सटेंशन-कुंजी डिफ़ॉल्ट मान"] --> res
wr["ऐप से फिर लिखना"] -.->|UCPD.sys रोकता है| uc
res ~~~ inst["इंस्टॉलर का काम"]
inst --> a1["ProgID और verb पंजीकृत करें"]
inst --> a2["OpenWithProgIds में जोड़ें"]
inst --> a3["Settings पेज पर ले जाएँ"]
चित्र 4: असोसिएशन समाधान उपयोगकर्ता की पसंद (UserChoice) को प्राथमिकता देता है, और OS उसे ऐप्स के फिर-लेखन से बचाता है।
3. «खोलें» के अलावा verb ── print, edit, runas, कस्टम verb
verb केवल open नहीं है। जिन मानक verb का अर्थ OS जानता है उनमें open के अलावा edit, print, play और preview भी हैं, और मानक verb को OS लोकेल के अनुसार प्रदर्शन नाम अपने आप मिलता है। डबल-क्लिक पर प्रयुक्त डिफ़ॉल्ट verb इस क्रम में तय होता है: shell कुंजी का डिफ़ॉल्ट मान → रजिस्ट्री में पहला verb → open → openwith।12
flowchart TB
accTitle: डिफ़ॉल्ट verb तय होने का क्रम
accDescr: डबल-क्लिक पर प्रयुक्त डिफ़ॉल्ट verb वह पहला है जो shell-कुंजी डिफ़ॉल्ट मान, रजिस्ट्री में पहला verb, open, openwith के क्रम में मिलता है
s1["shell-कुंजी डिफ़ॉल्ट मान"] -->|न हो तो| s2["रजिस्ट्री में पहला verb"]
s2 -->|न हो तो| s3["open"]
s3 -->|न हो तो| s4["openwith"]
चित्र 5: डबल-क्लिक का डिफ़ॉल्ट verb इसी क्रम में मिला पहला है।
अपनी क्रिया जोड़नी हो तो कस्टम verb पंजीकृत करें।
KomuraSoft.Report.1
shell
open
command
(Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
print
command
(Default) = "C:\Program Files\KomuraSoft\Report.exe" /print "%1"
verify ← कस्टम verb
(Default) = Verify report (&V) ← मेनू प्रदर्शन नाम
command
(Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"
तीन छोटी बातें जानना उपयोगी है।
- runas नाम का verb पंजीकृत करें तो «व्यवस्थापक के रूप में चलाएँ» के बराबर एलिवेशन लॉन्च परिभाषित होता है, और
ShellExecute-परिवार API जबrunasनिर्दिष्ट करे तब भी यही लगता है। - verb कुंजी पर
Extendedनाम का खाली मान रखें तो वह केवल Shift+राइट-क्लिक पर दिखने वाला विस्तारित verb बन जाता है। कम इस्तेमाल होने वाली खतरनाक क्रिया छिपाने के लिए सुविधाजनक।12 - पुराने ऐप के कुछ असोसिएशन अभी भी DDE (
ddeexecकुंजी) से दस्तावेज़ मौजूदा प्रोसेस में भेजते हैं, पर DDE से verb लॉन्च करना पहले से Deprecated विरासत है। नया लिखने का कोई कारण नहीं।12
एक और दुर्घटना अक्सर होती है कमांड लाइन पर उद्धरण। कमांड स्ट्रिंग का कोई तत्व स्पेस रख सकता हो तो उसे उद्धरण में लपेटना होगा। यह C:\Program Files\... जैसे EXE पथ पर तो लागू है ही, और %1 (चयनित फ़ाइल का पथ) हमेशा "%1" लिखा जाना चाहिए। उपयोगकर्ता के फ़ाइल पथ में स्पेस न होने की गारंटी नहीं। बिना उद्धरण वाला My Program.exe «My को तर्क Program.exe के साथ लॉन्च करो» समझा जाता है।13
flowchart TB
accTitle: कमांड लाइन पर उद्धरण दुर्घटना
accDescr: बिना उद्धरण वाली कमांड स्पेस पर टूटती है और My को Program.exe तर्क के साथ लॉन्च करने के रूप में गलत समझी जाती है, इसलिए स्पेस रख सकने वाला EXE पथ और चयनित फ़ाइल पथ दर्शाने वाला %1 हमेशा उद्धरण में लपेटें
c1["बिना उद्धरण कमांड"] -->|स्पेस पर टूटे| bad["दूसरा EXE लॉन्च समझने की गलती"]
c2["उद्धृत कमांड"] --> good["इरादे के अनुसार लॉन्च"]
c2 -.-> q1["EXE पथ उद्धरण में लपेटें"]
q1 -.-> q2["%1 भी हमेशा उद्धरण में लपेटें"]
चित्र 6: बिना उद्धरण कमांड स्पेस पर गलत टूटती है, इसलिए EXE पथ और %1 हमेशा उद्धरण में लपेटें।
अब तक की केवल-रजिस्ट्री मशीनरी (स्टैटिक verb) बिना कोई DLL लिखे पूरी हो सकती है, और एक्सप्लोरर को अस्थिर करने का जोखिम नहीं। Microsoft स्वयं बार-बार कहती है «शेल एक्सटेंशन लिखने से पहले सोचें कि आवश्यकता पूरी करने वाला सबसे सरल स्टैटिक verb काफी है या नहीं»।9
4. क्लासिक शेल एक्सटेंशन ── एक्सप्लोरर के अंदर चलने वाला DLL
4.1. शेल एक्सटेंशन के प्रकार
स्टैटिक verb जो आवश्यकताएँ नहीं पूरी कर सकता — «चयन के अनुसार मेनू गतिशील बदलें», «आइकन या प्रॉपर्टी शीट बदलें» — शेल-एक्सटेंशन हैंडलर इस्तेमाल करती हैं। प्रतिनिधि प्रकार निम्न हैं।4
| हैंडलर | मुख्य इंटरफ़ेस | क्या कर सकता है |
|---|---|---|
| कॉन्टेक्स्ट-मेनू हैंडलर | IContextMenu + IShellExtInit | मेनू आइटम गतिशील जोड़ें और नियंत्रित करें |
| आइकन हैंडलर / आइकन ओवरले | IExtractIcon / IShellIconOverlayIdentifier | प्रति-फ़ाइल आइकन और ओवरले |
| प्रॉपर्टी-शीट हैंडलर | IShellPropSheetExt | प्रॉपर्टी शीट में टैब जोड़ें |
| थंबनेल / इन्फ़ोटिप | IThumbnailProvider / IQueryInfo | थंबनेल व्यू और होवर विवरण |
| ड्रैग-एंड-ड्रॉप / कॉपी-हुक हैंडलर | IDropTarget / ICopyHook | ड्रॉप या कॉपी/मूव पर हस्तक्षेप |
ये सभी COM क्लास के रूप में लागू होते हैं और CLSID से रजिस्ट्री में पंजीकृत होते हैं। COM का विचार स्वयं «What Are COM / ActiveX / OCX? - The Differences and Relationships Explained» में है।
4.2. इन-प्रोसेस COM सर्वर होने का अर्थ
क्लासिक शेल एक्सटेंशन का सार यह है कि यह एक्सप्लोरर (या सामान्य फ़ाइल डायलॉग खोलने वाले किसी भी ऐप) में लोड होने वाला इन-प्रोसेस COM सर्वर (DLL) है। हर सावधानी इसी से निकलती है।4
- एक्सटेंशन क्रैश करे तो एक्सप्लोरर साथ गिरता है। अटक जाए तो राइट-क्लिक कई सेकंड जम जाता है। नुकसान केवल एक्सप्लोरर तक सीमित नहीं; फ़ाइल-खोलें डायलॉग दिखाने वाला हर ऐप पहुँच में आता है।
- मेनू निर्माण UI थ्रेड पर होता है, इसलिए मेनू दिखाने के समय नेटवर्क पहुँच या फ़ाइल I/O जैसा धीमा काम नहीं करना चाहिए।
- थ्रेडिंग मॉडल नियमतः
Apartmentपंजीकृत करें।
flowchart TB
accTitle: इन-प्रोसेस एक्सटेंशन की संपार्श्विक-क्षति संरचना
accDescr: शेल-एक्सटेंशन DLL न केवल एक्सप्लोरर में बल्कि फ़ाइल डायलॉग खोलने वाले किसी भी ऐप की प्रोसेस में लोड होता है, इसलिए एक्सटेंशन का क्रैश या हैंग पूरे होस्ट प्रोसेस तक फैलता है
dll["शेल-एक्सटेंशन DLL"] -->|इन-प्रोसेस लोड| exp["एक्सप्लोरर"]
dll -->|इन-प्रोसेस लोड| any["डायलॉग खोलने वाला कोई भी ऐप"]
exp --> dmg["क्रैश या हैंग फैलता है"]
any --> dmg
dmg -.-> rule["दिखाने के समय धीमा काम न करें"]
चित्र 7: एक्सटेंशन DLL होस्ट प्रोसेस के अंदर चलता है, इसलिए क्रैश या हैंग पूरे होस्ट तक फैलता है।
«विशेष फ़ोल्डर खोलने पर एक्सप्लोरर जम जाता है» या «राइट-क्लिक पाँच सेकंड लेता है» जैसी सलाह जाँचें तो कारण इन-हाउस ऐप नहीं, तीसरे पक्ष का शेल एक्सटेंशन होना असामान्य नहीं। अलगाव विधियाँ अध्याय 8 में हैं।
4.3. बिटनेस मिलाना ── 64-बिट वातावरण को 64-बिट DLL चाहिए
इन-प्रोसेस DLL को लोड करने वाली प्रोसेस की बिटनेस से मेल खाना चाहिए। 64-बिट Windows पर एक्सप्लोरर 64-बिट प्रोसेस है, इसलिए केवल 32-बिट बना शेल-एक्सटेंशन DLL कभी लोड नहीं होता और मेनू पर बिल्कुल नहीं दिखता। कोई त्रुटि भी नहीं, इसलिए «पंजीकृत किया पर नहीं दिखता» का आम कारण है। 32-बिट ऐप बॉडी के साथ 64-बिट शेल-एक्सटेंशन DLL वैध विन्यास है, पर COM पंजीकरण बिटनेस से बँटता है (Wow6432Node) — यह देखना होगा। verb की command से लॉन्च अलग-प्रोसेस EXE है, इसलिए इस बाधा के अधीन नहीं (32-बिट EXE छोड़ना ठीक है)।
flowchart TB
accTitle: शेल-एक्सटेंशन DLL की बिटनेस मिलान
accDescr: 64-बिट एक्सप्लोरर केवल 64-बिट शेल-एक्सटेंशन DLL लोड कर सकता है; केवल-32-बिट DLL मेनू पर नहीं दिखता और कोई त्रुटि नहीं देता; verb कमांड से लॉन्च EXE अलग प्रोसेस है और बाधा के अधीन नहीं
exp["64-बिट एक्सप्लोरर"] -->|लोड कर सकता है| d64["64-बिट शेल-एक्सटेंशन DLL"]
exp -.->|लोड नहीं कर सकता| d32["केवल-32-बिट DLL"]
d32 -.-> sym["मेनू पर नहीं, बिना त्रुटि"]
exe["verb से लॉन्च EXE"] -->|अलग प्रोसेस| ok32["32-बिट छोड़ना ठीक"]
चित्र 8: 64-बिट एक्सप्लोरर में लोड होने वाला केवल 64-बिट DLL है; verb से लॉन्च EXE इस बाधा के अधीन नहीं।
4.4. मैनेज्ड कोड में क्यों नहीं लिखना
अक्सर पूछा जाता है «क्या C# में शेल एक्सटेंशन लिख सकता हूँ», पर Microsoft ने साफ़ कहा है कि मैनेज्ड कोड (.NET) में इन-प्रोसेस शेल एक्सटेंशन लिखना अनुशंसित नहीं है और समर्थन से बाहर है।5
कारण यह है कि एक्सटेंशन किसी भी प्रोसेस में लोड होता है। CLR वर्शन टकराव (खासकर .NET Framework 4 से नीचे), लॉक की प्रतीक्षा करते CLR का संदेश लूप में फिर घुसना, और गारबेज कलेक्शन से अनिश्चित ऑब्जेक्ट लाइफ़टाइम का COM रेफ़रेंस-काउंट अनुबंध से टकराव — ये संरचनात्मक कारण होस्ट ऐप अस्थिर बनाते हैं। कुछ बिंदु .NET Framework 4 और बाद तथा आधुनिक .NET पर नरम हुए, पर आधिकारिक स्थिति नहीं बदली।
व्यावहारिक दिशा सरल है। इन-प्रोसेस एक्सटेंशन नेटिव C++ में लिखें। मैनेज्ड कोड चाहिए तो verb की command से लॉन्च सामान्य EXE बनाएँ, या अलग प्रोसेस में चलने वाला आउट-ऑफ़-प्रोसेस एक्सटेंशन (प्रीव्यू हैंडलर आदि)।5
flowchart TB
accTitle: मैनेज्ड कोड अनुमति का निर्णय
accDescr: एक्सप्लोरर के अंदर चलने वाला इन-प्रोसेस एक्सटेंशन नियमतः नेटिव C++ में लिखा जाता है; मैनेज्ड कोड चाहिए तो verb कमांड से लॉन्च सामान्य EXE या अलग प्रोसेस में चलने वाला आउट-ऑफ़-प्रोसेस एक्सटेंशन बनाएँ
q1{"इन-प्रोसेस चलता है?"} -->|हाँ| cpp["नेटिव C++ में लिखें"]
q1 -->|नहीं| mg["मैनेज्ड कोड ठीक है"]
cpp -.-> why["CLR / रीएंट्रेंसी जोखिम से होस्ट अस्थिर होता है"]
mg --> e1["verb-लॉन्च EXE"]
mg --> e2["आउट-ऑफ़-प्रोसेस प्रीव्यू"]
चित्र 9: इन-प्रोसेस एक्सटेंशन नियमतः नेटिव C++ है; मैनेज्ड कोड अलग प्रोसेस में चलने वाले विन्यास तक सीमित है।
5. Windows 11 का नया कॉन्टेक्स्ट मेनू ── दो भागों में बँटा मेनू
5.1. क्या हुआ
Windows 11 ने फ़ाइल एक्सप्लोरर का कॉन्टेक्स्ट मेनू नया किया। कट, कॉपी आदि ऊपर आइकन की पंक्ति बन गए; «खोलें» और «इससे खोलें» ऊपर एकत्र हुए; और ऐप द्वारा जोड़ी गई कमांड शेल की मानक कमांड के नीचे एकत्र होती हैं। एक ऐप कई कमांड जोड़े तो वे ऐप-नाम वाले फ़्लायआउट (सबमेनू) में इकट्ठा होती हैं।6
और निर्णायक बात यह है। क्लासिक IContextMenu-आधारित शेल एक्सटेंशन मिटाए नहीं गए; उन्हें «अधिक विकल्प दिखाएँ» (Shift+F10) से खुलने वाले पुराने-मेनू पक्ष पर ले जाया गया, जो Windows 10 मेनू ज्यों का त्यों लोड करता है।6 शुरुआती सलाह «मेनू छिप गया» की पहचान यही विभाजन है।
flowchart TB
accTitle: Windows 11 द्वारा दो भागों में बाँटा कॉन्टेक्स्ट मेनू
accDescr: राइट-क्लिक पर पहले खुलने वाला नया मेनू है; वहाँ वही कमांड दिखती हैं जो IExplorerCommand और पैकेज पहचान से पंजीकृत हैं; क्लासिक IContextMenu एक्सटेंशन अधिक विकल्प दिखाएँ से खुलने वाले पुराने मेनू पर चले जाते हैं
rc["फ़ाइल पर राइट-क्लिक"] --> newm["नया मेनू (Windows 11)"]
newm --> newi["IExplorerCommand + पहचान कमांड"]
newm -->|अधिक विकल्प Shift+F10| oldm["पुराना मेनू (Windows 10 मेनू)"]
oldm --> oldi["क्लासिक IContextMenu एक्सटेंशन"]
newi -.-> fly["कई कमांड फ़्लायआउट में इकट्ठा"]
चित्र 10: नए मेनू पर वही कमांड दिखती हैं जो IExplorerCommand + पहचान हैं; क्लासिक एक्सटेंशन पुराने-मेनू पक्ष पर चले जाते हैं।
5.2. नए मेनू का आधिकारिक मार्ग ── IExplorerCommand + मैनिफ़ेस्ट पंजीकरण
नए मेनू पर कस्टम कमांड रखने का एक ही तरीका है। IExplorerCommand इंटरफ़ेस लागू करने वाला नेटिव DLL तैयार करें, और MSIX पैकेज मैनिफ़ेस्ट में COM सर्वर तथा कॉन्टेक्स्ट-मेनू एक्सटेंशन घोषित करें।7
<!-- Package manifest (excerpt) -->
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="Komura commands">
<com:Class Id="01234567-89AB-CDEF-0123-456789ABCDEF"
Path="KomuraCommand.dll" ThreadingModel="STA" />
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type=".kmrpt">
<desktop5:Verb Id="VerifyReport"
Clsid="01234567-89AB-CDEF-0123-456789ABCDEF" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
ItemType का Type विशेष एक्सटेंशन, या * (सभी फ़ाइलें), Directory (फ़ोल्डर), या Directory\Background (फ़ोल्डर पृष्ठभूमि) निर्दिष्ट कर सकता है। DLL को एक्सप्लोरर की आर्किटेक्चर (64-बिट / ARM64) से मिलाएँ।7
IExplorerCommand स्वयं Windows 7 युग से मौजूद इंटरफ़ेस है; आप शीर्षक (GetTitle), आइकन (GetIcon), सक्षम / अक्षम / छिपा स्थिति (GetState), और निष्पादन (Invoke) लागू करते हैं। विधियाँ UI थ्रेड से बुलाई जाती हैं, इसलिए नेटवर्क संसाधनों तक पहुँच वर्जित है, और मेनू-निर्माण विधियों को जल्दी लौटना चाहिए। भारी काम Invoke के बाद करें।147
flowchart TB
accTitle: नए-मेनू पंजीकरण की मैनिफ़ेस्ट संरचना
accDescr: MSIX मैनिफ़ेस्ट की COM-सर्वर घोषणा CLSID को DLL से जोड़ती है, और कॉन्टेक्स्ट-मेनू-एक्सटेंशन घोषणा ItemType और Verb से लक्ष्य व इम्प्लीमेंटेशन बाँधती है, इसलिए कस्टम कमांड नए मेनू पर दिखती है
man["MSIX मैनिफ़ेस्ट"] --> com["COM-सर्वर घोषणा"]
man --> ctx["मेनू-एक्सटेंशन घोषणा"]
com -->|CLSID को DLL से जोड़ता है| impl["IExplorerCommand इम्प्लीमेंटेशन DLL"]
ctx -->|ItemType और Verb से निर्दिष्ट| impl
impl --> shown["कमांड नए मेनू पर दिखती है"]
ctx -.-> tgt["लक्ष्य एक्सटेंशन, सभी फ़ाइलें आदि"]
चित्र 11: मैनिफ़ेस्ट की दो घोषणाएँ इम्प्लीमेंटेशन DLL को लक्ष्य से बाँधती हैं, और कमांड नए मेनू पर दिखती है।
5.3. गैर-पैकेज्ड ऐप का विकल्प ── sparse package से केवल पहचान
«हमारा ऐप MSI के अलावा बाँटा नहीं जा सकता; MSIX असंभव है» का निकास द्वार sparse package (बाहरी लोकेशन वाला MSIX) है। आप केवल मैनिफ़ेस्ट वाला छोटा MSIX हस्ताक्षरित करते हैं, ऐप बॉडी के बिना, और मौजूदा इंस्टॉलर के अंत में पंजीकृत करते हैं। ऐप तब पैकेज पहचान पाता है, और ऊपर का मैनिफ़ेस्ट पंजीकरण (= नए मेनू पर दिखना) संभव होता है। Windows 10 संस्करण 2004 से उपलब्ध, पैकेज को लक्ष्य मशीन पर विश्वसनीय प्रमाणपत्र हस्ताक्षर चाहिए।8
flowchart TB
accTitle: sparse package से पहचान पाने का प्रवाह
accDescr: मौजूदा इंस्टॉलर ऐप बॉडी रखने के बाद, केवल-मैनिफ़ेस्ट sparse package को बाहरी लोकेशन से पंजीकृत करने पर ऐप पैकेज पहचान पाता है और नए-मेनू मैनिफ़ेस्ट पंजीकरण संभव होता है
inst["मौजूदा इंस्टॉलर"] --> files["ऐप बॉडी रखें"]
sp["sparse package"] -.-> only["केवल मैनिफ़ेस्ट, बॉडी नहीं"]
files --> reg["बाहरी लोकेशन से पंजीकृत करें"]
sp --> reg
reg --> id["पैकेज पहचान पाएँ"]
id --> ok["नए-मेनू पंजीकरण संभव"]
sp -.-> sign["विश्वसनीय हस्ताक्षर चाहिए"]
चित्र 12: बिना बॉडी वाला sparse package बाहरी लोकेशन से पंजीकृत करें, और ऐप पैकेज पहचान पाता है।
सबसे बड़ा लाभ यह है कि इंस्टॉलर बदलना नहीं पड़ता; जिसके पास पहले से MSI/EXE इंस्टॉलर संपत्ति है, उसके लिए यही व्यावहारिक उत्तर है। पूर्ण MSIX स्थानांतरण से तुलना के लिए «Choosing a Windows App Distribution Method - MSI/MSIX/ClickOnce/xcopy/Custom Updater» भी देखें।
5.4. असोसिएशन verb नए मेनू पर कैसे दिखते हैं
गलत समझ में आसान बिंदु: अध्याय 2 और 3 के असोसिएशन (ProgID और verb) नए मेनू पर अभी भी जीवित हैं। डबल-क्लिक का डिफ़ॉल्ट verb, «खोलें», और «इससे खोलें» उम्मीदवार असोसिएशन से हल होकर नए मेनू के ऊपर दिखते हैं। इसलिए अगर बस «इस ऐप से खोल सकें» चाहिए, Windows 11 पर अतिरिक्त काम नहीं। दूसरी ओर, असोसिएशन सामान्य-उद्देश्य मेनू एक्सटेंशन नहीं है, इसलिए नए मेनू की पहली परत पर मनमानी कस्टम कमांड चाहिए तो IExplorerCommand प्लस पहचान — यही भूमिका विभाजन है।7
flowchart TB
accTitle: असोसिएशन और नए मेनू का भूमिका विभाजन
accDescr: ProgID-और-verb असोसिएशन नए मेनू पर अभी भी डिफ़ॉल्ट verb, खोलें और इससे खोलें हल करने के लिए लगता है और ऊपर दिखता है; नए मेनू की पहली परत पर मनमानी कस्टम कमांड के लिए IExplorerCommand और पहचान चाहिए
assoc["असोसिएशन (ProgID + verb)"] --> sol["डिफ़ॉल्ट / खोलें हल करें"]
sol --> top["नए मेनू का ऊपर"]
assoc -.-> keep["Win11 पर अतिरिक्त काम नहीं"]
cmd["कस्टम कमांड"] --> need["IExplorerCommand+पहचान"]
need --> first["नए मेनू की पहली परत"]
चित्र 13: असोसिएशन नए मेनू पर अभी भी «खोलें» परिवार का समाधान करते हैं; केवल कस्टम कमांड को IExplorerCommand प्लस पहचान चाहिए।
6. व्यावहारिक निर्णय तालिका ── तीन विकल्पों में से कौन
अब तक को व्यावहारिक तीन-तरफ़ा चुनाव में बाँधते हैं।
| क्या हासिल करना है | अनुशंसित साधन | Windows 11 पर रूप | आवश्यक काम और लागत |
|---|---|---|---|
| (क) डबल-क्लिक या «खोलें» पर इन-हाउस ऐप लॉन्च | असोसिएशन + स्टैटिक verb (केवल रजिस्ट्री पंजीकरण) | नए मेनू के «खोलें» और «इससे खोलें» में एकीकृत | केवल इंस्टॉलर रजिस्ट्री पंजीकरण। कोई DLL नहीं, अतिरिक्त हस्ताक्षर आवश्यकता नहीं |
| (ख) चयनित फ़ाइल/फ़ोल्डर के लिए कस्टम कमांड नए मेनू पर | IExplorerCommand इम्प्लीमेंटेशन + MSIX मैनिफ़ेस्ट पंजीकरण। गैर-पैकेज्ड ऐप को sparse package से पहचान | नए मेनू की पहली परत (कई कमांड ऐप-नाम फ़्लायआउट में) | नेटिव C++ DLL + पैकेज पहचान + कोड हस्ताक्षर |
| (ग) मौजूदा क्लासिक IContextMenu एक्सटेंशन जारी रखें | फिलहाल जैसा है वैसा रखें (नए विकास के लिए न चुनें) | केवल पुराने-मेनू पक्ष, «अधिक विकल्प दिखाएँ» (Shift+F10) के नीचे | 64-बिट बिल्ड और COM पंजीकरण बनाए रखें। बाद में (ख) पर जाने की योजना |
दो निर्णय बिंदु। पहला, (क) पूरी करने वाली आवश्यकता के लिए (ख) या (ग) न लाएँ। शेल एक्सटेंशन लिखते ही एक्सप्लोरर की स्थिरता की ज़िम्मेदारी आपके सिर। दूसरा, (ग) केवल «टूटा नहीं»; उपयोगकर्ता अनुभव में एक कदम कमज़ोर रहता है। दैनिक संचालन में जितनी बार कमांड लगे, (ख) पर जाने का प्रतिफल उतना बड़ा।
flowchart TB
accTitle: तीन विकल्पों में कैसे चुनें
accDescr: अगर बस डबल-क्लिक या खोलें पर लॉन्च चाहिए तो असोसिएशन और स्टैटिक verb काफी; नए मेनू पर कस्टम कमांड के लिए IExplorerCommand और MSIX मैनिफ़ेस्ट पंजीकरण; MSIX न बन सके तो sparse package से पहचान; मौजूदा क्लासिक IContextMenu फिलहाल पुराने-मेनू पक्ष पर रखें
q1{"खोलें काफी है?"} -->|हाँ| pa["असोसिएशन + स्टैटिक verb"]
q1 -->|नहीं| q2{"नए मेनू पर कस्टम?"}
q2 -->|हाँ| q3{"MSIX बन सकते हैं?"}
q3 -->|हाँ| pb1["IExplorerCommand+MSIX"]
q3 -->|नहीं| pb2["sparse-pkg पहचान"]
q2 -->|नहीं| pc["फिलहाल क्लासिक रखें"]
pc -.-> old["केवल पुराने-मेनू पक्ष"]
pa -.-> dllfree["कोई DLL नहीं, कम जोखिम"]
चित्र 14: आवश्यकता के अनुसार स्टैटिक verb, IExplorerCommand प्लस पहचान, और क्लासिक बनाए रखने में चुनें।
7. व्यवहार में परिनियोजन और पंजीकरण ── इंस्टॉलर, sparse package, सफ़ाई
7.1. HKLM या HKCU
इंस्टॉलर के आकार से मिलाएँ। सभी-उपयोगकर्ता (Program Files के नीचे, व्यवस्थापक अधिकार) HKLM\Software\Classes है; प्रति-उपयोगकर्ता इंस्टॉल (बिना एलिवेशन) HKCU\Software\Classes। मिलाएँ तो «A खोल सकता है पर B नहीं» जैसी पूछताछ पैदा होती है। CLSID पंजीकरण वाले शेल एक्सटेंशन के लिए Reg-Free COM — जो रजिस्ट्री पंजीकरण स्वयं अनावश्यक बनाता है — इन-ऐप COM उपयोग के लिए वैध विकल्प है, पर एक्सप्लोरर द्वारा लोड शेल एक्सटेंशन पर लागू नहीं होता, इसलिए सीधा पंजीकरण चाहिए («What Is Reg-Free COM - Using COM Without Registration»)।
7.2. बदलाव के बाद सूचित करें ── SHChangeNotify
असोसिएशन पंजीकृत, बदला या हटाया हो तो SHChangeNotify से SHCNE_ASSOCCHANGED ईवेंट सूचित करें। यह छोड़ें तो एक्सप्लोरर रीबूट तक बदलाव न देख सकता।110
// Call once after changing associations, e.g. from an installer custom action
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
7.3. sparse package पंजीकृत करना और हटाना
sparse package पंजीकृत करना और हटाना इंस्टॉलर का काम है। फ़ाइलें रखने के बाद पंजीकृत करें; फ़ाइलें हटाने से पहले हटाएँ।8
# At install time: after placing the files, register the install folder as the external location
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
-ExternalLocation "C:\Program Files\KomuraSoft"
# At uninstall time: remove the package registration before deleting the files
Remove-AppxPackage <package full name>
देखने योग्य बिंदु: Add-AppxPackage उसे चलाने वाले उपयोगकर्ता के लिए पंजीकृत करता है। प्रति-मशीन MSI की कस्टम एक्शन से, LocalSystem के अधीन चलाएँ तो इंस्टॉल करने वाले उपयोगकर्ता को पहचान नहीं मिलती, इसलिए उपयोगकर्ता इम्पर्सोनेशन के अधीन चलाएँ। तब भी इम्पर्सोनेशन के तहत पंजीकरण केवल उस उपयोगकर्ता का है जिसने वह इंस्टॉल चलाया। कई उपयोगकर्ता वाले PC पर अन्य उपयोगकर्ता और बाद में बने उपयोगकर्ता के पास पैकेज पहचान नहीं, और कमांड नए मेनू पर नहीं दिखती। हर उपयोगकर्ता को चाहिए तो पहली लॉन्च पर अपना पैकेज पंजीकरण जाँचें और न हो तो पंजीकृत करें (प्रति-उपयोगकर्ता पंजीकरण), और अनइंस्टॉल योजना में हर पंजीकृत उपयोगकर्ता से हटाना शामिल करें। मैनिफ़ेस्ट पंजीकरण प्रतिबिंबित करने के लिए एक्सप्लोरर रीस्टार्ट (या साइन-आउट) भी चाहिए हो सकता है।7
flowchart TB
accTitle: sparse package पंजीकृत और हटाने का क्रम
accDescr: इंस्टॉल पर फ़ाइलें रखने के बाद sparse package पंजीकृत करें; अनइंस्टॉल पर फ़ाइलें हटाने से पहले पंजीकरण हटाएँ; ध्यान दें पंजीकरण केवल चलाने वाले उपयोगकर्ता के लिए प्रभावी है
i1["इंस्टॉल"] --> i2["फ़ाइलें रखें"]
i2 --> i3["sparse package पंजीकृत करें"]
u1["अनइंस्टॉल"] --> u2["पैकेज पंजीकरण हटाएँ"]
u2 --> u3["फ़ाइलें हटाएँ"]
i3 -.-> pu["पंजीकरण केवल चल रहे उपयोगकर्ता पर प्रभावी"]
चित्र 15: फ़ाइलें रखने के बाद पंजीकृत करें, हटाने से पहले हटाएँ, और ध्यान दें पंजीकरण चल रहे उपयोगकर्ता के अनुसार है।
7.4. अनइंस्टॉल पर सफ़ाई ── क्या हटाएँ, क्या छोड़ें
अनइंस्टॉल सफ़ाई की स्पष्ट आधिकारिक-मार्गदर्शन रेखा है।1
- हटाएँ: पूरा इन-हाउस ProgID कुंजी, Capabilities/RegisteredApplications पंजीकरण, शेल एक्सटेंशन का CLSID पंजीकरण, sparse package (Remove-AppxPackage)।
- छोड़ें: एक्सटेंशन कुंजी (
.kmrpt) का डिफ़ॉल्ट मान। आधिकारिक सिफ़ारिश है कि भले वह अभी भी इन-हाउस ProgID की ओर इशारा करे, न हटाएँ। इंस्टॉल के बाद तय करना कठिन है कि किसी अन्य ऐप ने डिफ़ॉल्ट ले लिया या नहीं, और Windows अपंजीकृत डिफ़ॉल्ट-मान ProgID को बस अनदेखा करता है, इसलिए छोड़ने से वास्तविक हानि नहीं। - सफ़ाई के अंत में भी SHChangeNotify(SHCNE_ASSOCCHANGED) बुलाएँ।
अधिकांश «अनइंस्टॉल किया और मेनू पर अवशेष अभी भी दिखते हैं» समस्याएँ इसी सफ़ाई डिज़ाइन की लीक हैं।
flowchart TB
accTitle: अनइंस्टॉल पर सफ़ाई डिज़ाइन
accDescr: अनइंस्टॉल पर इन-हाउस ProgID कुंजी, CLSID पंजीकरण और sparse package हटाएँ; एक्सटेंशन-कुंजी डिफ़ॉल्ट मान छोड़ें क्योंकि अपंजीकृत ProgID अनदेखा होता है; सफ़ाई के अंत में SHChangeNotify से बदलाव सूचित करें
un["अनइंस्टॉल"] --> del["हटाएँ"]
un --> keep["छोड़ें"]
del --> d1["ProgID और CLSID पंजीकरण"]
del --> d2["sparse package"]
keep --> k1["एक्सटेंशन-कुंजी डिफ़ॉल्ट मान"]
k1 -.-> why["अपंजीकृत ProgID अनदेखा होता है"]
d1 --> fin["अंत में SHChangeNotify से सूचित करें"]
k1 --> fin
चित्र 16: इन-हाउस पंजीकरण हटाएँ, एक्सटेंशन-कुंजी डिफ़ॉल्ट मान छोड़ें, और सफ़ाई के अंत में बदलाव सूचित करें।
8. समस्या-निवारण ── गायब, दोहरा, भारी
8.1. मेनू पर नहीं दिखता
इस क्रम में अलग करें।
- आप कौन सा मेनू देख रहे हैं: क्लासिक-शैली पंजीकरण केवल Shift+F10 वाले पुराने-मेनू पक्ष पर दिखता है। पहले दोनों जाँचें।
- बिटनेस: केवल-32-बिट शेल-एक्सटेंशन DLL 64-बिट एक्सप्लोरर में लोड नहीं होता (खंड 4.3)।
- पंजीकरण गंतव्य: HKLM/HKCU, Wow6432Node गड़बड़।
reg queryसे वास्तविक कुंजी पुष्टि करें। - पैकेज पंजीकरण: नए मेनू के लिए
Get-AppxPackageसे उपस्थिति, हस्ताक्षर प्रमाणपत्र का विश्वास, और-ExternalLocationपथ पुष्टि करें, फिर एक्सप्लोरर रीस्टार्ट करें।7 - छूटी सूचना: SHChangeNotify भूल गए हों तो एक्सप्लोरर रीस्टार्ट से प्रभावी होता है या नहीं, इससे पता चलता है।
flowchart TB
accTitle: मेनू पर न दिखने पर अलगाव क्रम
accDescr: पहले पुष्टि करें आप कौन सा मेनू देख रहे हैं, फिर DLL बिटनेस, रजिस्ट्री पंजीकरण गंतव्य, पैकेज पंजीकरण और हस्ताक्षर, तथा छूटा SHChangeNotify, इसी क्रम में अलग करें
c1["पुष्टि करें पुराना या नया मेनू"] --> c2["DLL बिटनेस पुष्टि करें"]
c2 --> c3["HKLM और HKCU पंजीकरण गंतव्य पुष्टि करें"]
c3 --> c4["पैकेज पंजीकरण और हस्ताक्षर पुष्टि करें"]
c4 --> c5["रीस्टार्ट से छूटी सूचना पहचानें"]
चित्र 17: «नहीं दिखता» पर मेनू जो देख रहे हैं, बिटनेस, पंजीकरण गंतव्य, पैकेज पंजीकरण, छूटी सूचना के क्रम में अलग करें।
8.2. दो बार दिखता है, या हटता नहीं
विशिष्ट कारण क्लासिक रजिस्ट्री पंजीकरण और मैनिफ़ेस्ट पंजीकरण का साथ-साथ रहना, अनइंस्टॉल सफ़ाई की लीक (खंड 7.4), या पुराने-संस्करण ProgID के अवशेष हैं। केवल पुराने मेनू पर दो बार दिखे तो अवशेष सोचें; पुराने और नए दोनों पर दिखे तो साथ-साथ सोचें।
flowchart TB
accTitle: दोहरी प्रदर्शन अलग करना
accDescr: केवल पुराने मेनू पर दो बार सफ़ाई लीक या पुराने ProgID जैसे अवशेष की ओर इशारा करता है; पुराने और नए दोनों पर दो बार क्लासिक रजिस्ट्री पंजीकरण और मैनिफ़ेस्ट पंजीकरण के साथ-साथ की ओर
q{"किस पर दो बार दिखता है?"} -->|केवल पुराना मेनू| zan["अवशेष"]
q -->|पुराना और नया| hei["साथ-साथ"]
zan -.-> z1["सफ़ाई लीक या बचा पुराना ProgID"]
hei -.-> h1["क्लासिक रजिस्ट्री पंजीकरण नए के साथ"]
चित्र 18: केवल पुराने मेनू पर दो बार अवशेष की ओर; पुराने और नए दोनों पर दो बार साथ-साथ की ओर।
8.3. एक्सप्लोरर भारी है या क्रैश करता है
राइट-क्लिक धीमा हो, या विशेष फ़ोल्डर क्रैश करे, पहले इंस्टॉल शेल एक्सटेंशन की सूची बनाएँ। NirSoft के ShellExView जैसे उपकरण से गैर-Microsoft एक्सटेंशन सूचीबद्ध करें, संदिग्ध अस्थायी बंद करें, और बाइनरी खोज से दोषी DLL पहचानें। क्रैश पर Event Viewer का «Faulting module» भी सुराग है। इन-हाउस एक्सटेंशन कारण हो तो मेनू-निर्माण पथ पर सिंक्रोनस I/O या नेटवर्क पहुँच संदेह करें (खंड 4.2 और 5.2)।
flowchart TB
accTitle: भारी या क्रैश पर दोषी DLL पहचानना
accDescr: ShellExView में गैर-Microsoft शेल एक्सटेंशन सूचीबद्ध करें, संदिग्ध अस्थायी बंद करें और बाइनरी खोज से दोषी DLL पहचानें; क्रैश पर Event Viewer का faulting module भी सुराग है
s1["शेल एक्सटेंशन सूचीबद्ध करें"] --> s2["गैर-Microsoft सूचीबद्ध करें"]
s2 --> s3["अस्थायी बंद करें और बाइनरी खोज"]
s3 --> s4["दोषी DLL पहचानें"]
crash["क्रैश पर"] -.-> ev["faulting module जाँचें"]
ev -.-> s4
चित्र 19: गैर-Microsoft एक्सटेंशन अस्थायी बंद करें और बाइनरी खोज करें; क्रैश पर Event Viewer भी इस्तेमाल करें।
8.4. सत्यापन के लिए Windows Sandbox सुविधाजनक है
शेल इंटीग्रेशन का सत्यापन «स्वच्छ वातावरण पर इंस्टॉल → चलाएँ → अनइंस्टॉल → अवशेष शून्य» की पुष्टि पर आधारित है। यहाँ सुविधाजनक Windows Sandbox (Pro/Enterprise/Education) है: हर लॉन्च कुछ सेकंड में नया डिस्पोज़ेबल Windows लाता है, इसलिए इंस्टॉलर पंजीकरण और सफ़ाई परीक्षण जितनी बार चाहें चला सकते हैं। बंद करें तो सब गायब, इसलिए अवशेष-रजिस्ट्री जाँच के लिए भी उपयुक्त।15
9. सारांश
- फ़ाइल असोसिएशन «एक्सटेंशन कुंजी → ProgID → verb» की तीन-परत संरचना है, और HKCR HKLM/HKCU Classes का मर्ज्ड व्यू है। लिखने का गंतव्य स्पष्ट नामें, और
%1हमेशा उद्धरण में लपेटें। - डिफ़ॉल्ट ऐप उपयोगकर्ता द्वारा चुने जाने के लिए डिज़ाइन है और प्रोग्राम से नहीं बदला जा सकता। इंस्टॉलर का काम उम्मीदवार के रूप में सही पंजीकरण है।
- क्लासिक शेल एक्सटेंशन एक्सप्लोरर में लोड इन-प्रोसेस COM DLL है। क्रैश या देरी पूरे तक फैलती है; 64-बिट चाहिए; मैनेज्ड कोड असमर्थित; नियम नेटिव C++ इम्प्लीमेंटेशन है।
- Windows 11 पर कॉन्टेक्स्ट मेनू दो भागों में बँट गया। नए मेनू पर कस्टम कमांड के लिए IExplorerCommand प्लस MSIX मैनिफ़ेस्ट चाहिए; क्लासिक IContextMenu «अधिक विकल्प दिखाएँ» पक्ष पर चला जाता है।
- जो ऐप MSIX नहीं बन सकता, उसके लिए sparse package (बाहरी लोकेशन वाला MSIX) से पहचान व्यावहारिक उत्तर है।
- अगर बस «इस ऐप से खोलें» चाहिए, असोसिएशन और स्टैटिक verb अभी भी काफी हैं। सबसे सरल साधन से शुरू करना आधिकारिक दिशानिर्देश भी है।
- पंजीकरण, बदलाव या हटाने के बाद SHChangeNotify से सूचित करें; अनइंस्टॉल पर ProgID हटाएँ पर एक्सटेंशन-कुंजी डिफ़ॉल्ट मान छोड़ें। सत्यापन के लिए Windows Sandbox सुविधाजनक है।
Windows 11 PC बदलने पर «मेनू छिप गया» दिखे तो पहले अध्याय 6 की निर्णय तालिका में (क), (ख) और (ग) में से कौन है पुष्टि करें। काम का पैमाना वहीं आँक सकना चाहिए।
संबंधित लेख
- What Are COM / ActiveX / OCX? - The Differences and Relationships Explained
- What Is Reg-Free COM - Using COM Without Registration
- Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the “The Value I Wrote Isn’t There” Problem
- Choosing a Windows App Distribution Method - MSI/MSIX/ClickOnce/xcopy/Custom Updater
- DLL and COM Interface Backward Compatibility — A Decision Table for Which Changes Break Callers
- Windows ऐप संगतता कैसे काम करती है ── संगतता मोड, shim और Compatibility Administrator से पुराने ऐप जीवित रखना
संबंधित परामर्श क्षेत्र
KomuraSoft LLC व्यावसायिक ऐप के लिए फ़ाइल असोसिएशन, कॉन्टेक्स्ट मेनू और शेल एक्सटेंशन का डिज़ाइन व इम्प्लीमेंटेशन; Windows 11 नए कॉन्टेक्स्ट मेनू को निशाना (IExplorerCommand पर जाना, sparse package लाना); मौजूदा इंस्टॉलर के पंजीकरण और सफ़ाई की समीक्षा; तथा एक्सप्लोरर भारी होने या क्रैश करने का कारण जाँच सँभालती है। «अधिक विकल्प दिखाएँ के नीचे छिपे मेनू के साथ क्या करें» तय करने से शुरू करना ठीक है।
- Windows ऐप विकास
- मौजूदा संपत्तियों का पुनरुपयोग और माइग्रेशन
- तकनीकी परामर्श और डिज़ाइन समीक्षा
- संपर्क करें
संदर्भ लिंक
-
Microsoft Learn, File Types. एक्सटेंशन कुंजी के ProgID की ओर इशारा करने की संरचना; OpenWithProgIds; HKLM/HKCU\Software\Classes पर पंजीकरण विभाजन; असोसिएशन बदलाव के बाद SHChangeNotify(SHCNE_ASSOCCHANGED) बुलाना; और अनइंस्टॉल पर ProgID हटाना पर एक्सटेंशन कुंजी का डिफ़ॉल्ट मान छोड़ना। ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, HKEY_CLASSES_ROOT Key. HKEY_CLASSES_ROOT HKLM\Software\Classes और HKCU\Software\Classes का मर्ज्ड व्यू है; उपयोगकर्ता-पक्ष परिभाषाएँ मशीन-पक्ष से पहले आती हैं; और लेखन पर वितरण नियम। ↩ ↩2
-
Microsoft Learn, Windows app defaults platform. डिफ़ॉल्ट ऐप बदलना केवल सिस्टम Settings UI से करने के लिए डिज़ाइन; उपयोगकर्ता-सेटिंग डेटा अस्पष्ट और फ़िल्टर ड्राइवर (UCPD.sys) से लेखन-सुरक्षित; रजिस्ट्री-आधारित बदलाव असमर्थित; प्रबंधित वातावरण में Group Policy / MDM नीति। ↩ ↩2
-
Microsoft Learn, Working with Shell Extensions. शेल-एक्सटेंशन हैंडलर के प्रकार; एक्सटेंशन एक्सप्लोरर (और शेल होस्ट करने वाली प्रोसेस) में लोड इन-प्रोसेस COM DLL है इसलिए क्रैश या हैंग पूरे एक्सप्लोरर तक फैलता है; ThreadingModel=Apartment से पंजीकरण; शेल एक्सटेंशन से पहले सरल विकल्प सोचें। ↩ ↩2 ↩3
-
Microsoft Learn, Guidance for Implementing In-Process Extensions. Microsoft मैनेज्ड कोड में इन-प्रोसेस शेल-एक्सटेंशन इम्प्लीमेंटेशन अनुशंसित और समर्थित नहीं करती; कारणों में CLR वर्शन टकराव, रीएंट्रेंसी और अनिश्चित ऑब्जेक्ट लाइफ़टाइम; आउट-ऑफ़-प्रोसेस एक्सटेंशन (प्रीव्यू हैंडलर, या shell\verb\command से लॉन्च) के लिए मैनेज्ड कोड स्वीकार्य। ↩ ↩2 ↩3
-
Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. Windows 11 नए कॉन्टेक्स्ट मेनू का डिज़ाइन; IExplorerCommand प्लस ऐप पहचान से विस्तार; «खोलें» और «इससे खोलें» ऊपर रखना; कई कमांड ऐप-नाम फ़्लायआउट में इकट्ठा करना; क्लासिक IContextMenu एक्सटेंशन «अधिक विकल्प दिखाएँ» (Shift+F10) के तहत Windows 10 मेनू के रूप में लोड। ↩ ↩2 ↩3
-
Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. Windows 11 नए कॉन्टेक्स्ट मेनू पर पंजीकरण IExplorerCommand इम्प्लीमेंटेशन प्लस windows.comServer प्लस desktop4:FileExplorerContextMenus मैनिफ़ेस्ट घोषणा से; ItemType *, Directory या Directory\Background निर्दिष्ट कर सकता है; DLL आर्किटेक्चर मिलान; मेनू-निर्माण विधियाँ तेज़ रखें; गैर-पैकेज्ड ऐप को sparse package से ढकें; पंजीकरण प्रभावी होने के लिए कभी एक्सप्लोरर रीस्टार्ट चाहिए; फ़ाइल असोसिएशन सामान्य-उद्देश्य मेनू एक्सटेंशन नहीं। ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Grant package identity by packaging with external location. मौजूदा इंस्टॉलर बदले बिना बाहरी-लोकेशन पैकेज (sparse package) पंजीकृत कर पैकेज पहचान पाना; Windows 10 संस्करण 2004 से उपलब्ध; पहचान-आवश्यक Windows सुविधाएँ (कॉन्टेक्स्ट-मेनू पंजीकरण, नोटिफिकेशन आदि) प्रयोग योग्य होना। ↩ ↩2 ↩3
-
Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. आवश्यकता पूरी करने वाला सबसे सरल स्टैटिक-verb तरीका चुनें; IContextMenu सबसे शक्तिशाली पर सबसे जटिल और गैर-अनुशंसित ओर वर्गीकृत; IExplorerCommand/IExplorerCommandState अनुशंसित तरीका। ↩ ↩2
-
Microsoft Learn, SHChangeNotify function. फ़ाइल-असोसिएशन बदलाव सिस्टम को सूचित करने वाला SHCNE_ASSOCCHANGED ईवेंट कैसे उठाएँ, और शेल बदलाव देखे इसके लिए उसका उपयोग। ↩ ↩2
-
Microsoft Learn, Application Registration. App Paths उपकुंजी से निष्पादन योग्य पंजीकरण अनुशंसित; Applications उपकुंजी की भूमिका; SystemFileAssociations से verb पंजीकरण; और डिफ़ॉल्ट ऐप बदलने पर ProgID तथा संबंधित जानकारी की प्राथमिकता। ↩
-
Microsoft Learn, Verbs and File Associations. verb ShellExecuteEx द्वारा भी प्रयुक्त क्रिया है; स्पेस रख सकने वाले कमांड-स्ट्रिंग तत्व उद्धरण में लपेटें और “%1” हमेशा उद्धृत लिखें; HKCR\Applications के तहत डिफ़ॉल्ट प्रक्रिया पंजीकरण। ↩
-
Microsoft Learn, IExplorerCommand interface. GetTitle, GetIcon, GetState, Invoke, EnumSubCommands आदि विधियों की बनावट; विधियाँ UI थ्रेड पर बुलाई जाती हैं इसलिए नेटवर्क संसाधनों से संवाद न करें; Windows Vista से उपलब्ध। ↩
-
Microsoft Learn, Windows Sandbox. कुछ सेकंड में डिस्पोज़ेबल, पृथक Windows वातावरण लॉन्च; बंद करने पर सभी बदलाव त्यागे जाते हैं; सॉफ़्टवेयर परीक्षण और इंस्टॉलर सत्यापन के लिए उपयुक्त; Pro/Enterprise/Education पर उपलब्ध। ↩
संबंधित लेख
निकटवर्ती विषयों में गहराई से जाने के लिए समान टैग वाले नवीनतम लेख।
क्लिपबोर्ड और ड्रैग एंड ड्रॉप कैसे काम करते हैं — व्यावसायिक ऐप में OLE डेटा ट्रांसफ़र सही सँभालना
Excel तालिका चिपकाएँ और फ़ॉर्मेटिंग बिखर जाए; स्रोत ऐप बंद करें और चिपकाना बंद हो जाए — दोनों इसलिए कि क्लिपबोर्ड एक ही सामग्री कई फ़ॉर्म...
Win32 Thread Pool API — CreateThreadpoolWork से थ्रेड बनाए बिना समवर्तिता
क्या आपके नेटिव कोड में CreateThread कॉल बिखरी पड़ी हैं? यह लेख Vista में पुनर्डिज़ाइन की गई Win32 थ्रेड पूल API — work, timer, wait और i...
Named Pipes व्यवहार में — डिज़ाइन से सुरक्षा तक, Windows की मानक IPC
Named pipes — Windows की मानक इंटर-प्रोसेस कम्युनिकेशन — की व्यावहारिक मार्गदर्शिका। यह लेख प्राथमिक स्रोतों से बाइट और मैसेज मोड का चुना...
स्लीप से रिज़्यूम पर टूटने वाले ऐप — Windows पावर इवेंट कैसे काम करते हैं और उनसे बचने वाले व्यावसायिक ऐप कैसे बनाएँ
लैपटॉप खोला और व्यावसायिक ऐप के कनेक्शन मर चुके थे — कारण वह डिज़ाइन है जिसने स्लीप का हिसाब ही नहीं रखा। यह लेख WM_POWERBROADCAST सूचना ...
DllMain और Loader Lock — DLL आरंभीकरण में "कुछ न करें" कहे जाने का वास्तविक कारण
DllMain से LoadLibrary क्यों न बुलाएँ या दूसरे थ्रेड से सिंक्रोनाइज़ न करें। प्राथमिक स्रोतों से यह लेख समझाता है कि लोडर लॉक हर DLL सूचन...
संबंधित विषय
ये पृष्ठ विषय को सेवाओं और निर्णयों के व्यापक संदर्भ में रखते हैं।
Windows के तकनीकी विषय
Windows विकास, बग जाँच और मौजूदा संपत्तियों के उपयोग का प्रवेश-द्वार।
ActiveX माइग्रेशन
COM / ActiveX / OCX कॉम्पोनेन्ट रखने, रैप करने या बदलने के निर्णय।
इस विषय से जुड़ी सेवाएँ
यह लेख निम्नलिखित सेवाओं से सीधे जुड़ा है।
Windows ऐप विकास
व्यावसायिक ऐप, डिवाइस एकीकरण और संचार उपकरण, आवश्यकताओं से विकास तक।
Windows सॉफ़्टवेयर का रखरखाव और आधुनिकीकरण
मौजूदा Windows सॉफ़्टवेयर का विस्तार, रखरखाव और चरणबद्ध आधुनिकीकरण।
अक्सर पूछे जाने वाले प्रश्न
इस लेख के विषय पर परामर्श में अक्सर पूछे जाने वाले प्रश्न।
- Windows 11 पर हमारे ऐप का कॉन्टेक्स्ट-मेनू आइटम केवल "अधिक विकल्प दिखाएँ" के नीचे क्यों दिखाई देता है?
- क्योंकि Windows 11 पर फ़ाइल एक्सप्लोरर का कॉन्टेक्स्ट मेनू दो परतों में बँट गया, पुराना और नया। नए मेनू पर वे ही कमांड आ सकती हैं जो IExplorerCommand इंटरफ़ेस लागू करती हैं और MSIX पैकेज मैनिफ़ेस्ट में पंजीकृत हैं (= उनके पास पैकेज पहचान है)। क्लासिक IContextMenu-आधारित शेल एक्सटेंशन उस पुराने मेनू पर चले गए जिसे आप "अधिक विकल्प दिखाएँ" (Shift+F10) से खोलते हैं। एक्सटेंशन स्वयं टूटा नहीं है, इसलिए फिलहाल काम करता रहता है, लेकिन नए मेनू पर चाहिए तो IExplorerCommand पर माइग्रेशन और या तो MSIX पैकेजिंग या sparse package से पहचान देना ज़रूरी है।
- क्या इंस्टॉलर हमारे ऐप को किसी फ़ाइल का डिफ़ॉल्ट ऐप (डबल-क्लिक पर खुलने वाला) सेट कर सकता है?
- नहीं। डिफ़ॉल्ट ऐप चुनना उपयोगकर्ता का काम माना गया है, और Windows सिस्टम Settings UI के अलावा कहीं से डिफ़ॉल्ट ऐप बदलने का समर्थन नहीं करता। हर उपयोगकर्ता की पसंद रखने वाली UserChoice जानकारी अस्पष्ट की गई है, और एक फ़िल्टर ड्राइवर (UCPD.sys) ऐप्स से लिखने से भी बचाता है। इंस्टॉलर ProgID और verb पंजीकृत कर सकता है, खुद को OpenWithProgIds में जोड़कर "इससे खोलें" के उम्मीदवार के रूप में दिख सकता है, और उपयोगकर्ता को Default apps सेटिंग पेज पर ले जा सकता है। सही इम्प्लीमेंटेशन डिफ़ॉल्ट चुराना नहीं, चुने जाने के लिए तैयार रहना है।
- क्या मैं C# जैसी मैनेज्ड कोड में शेल एक्सटेंशन लिख सकता हूँ?
- Microsoft ने साफ़ कहा है कि इन-प्रोसेस शेल एक्सटेंशन (कॉन्टेक्स्ट-मेनू हैंडलर, आइकन हैंडलर आदि) मैनेज्ड कोड में लिखना अनुशंसित नहीं है और असमर्थित है। एक्सटेंशन एक्सप्लोरर में और किसी भी ऐप की प्रोसेस में लोड होता है जो सामान्य फ़ाइल डायलॉग खोलता है, इसलिए CLR वर्शन टकराव, रीएंट्रेंसी और अनिश्चित ऑब्जेक्ट लाइफ़टाइम होस्ट ऐप को अस्थिर बनाते हैं। नियम नेटिव C++ में इम्प्लीमेंटेशन है। verb की command से लॉन्च होने वाला सामान्य EXE, या अलग प्रोसेस में चलने वाला आउट-ऑफ़-प्रोसेस एक्सटेंशन जैसे प्रीव्यू हैंडलर, मैनेज्ड कोड में ठीक है।
- sparse package (बाहरी लोकेशन वाला MSIX) क्या है?
- एक छोटा MSIX पैकेज जिसमें ऐप फ़ाइलें नहीं, केवल मैनिफ़ेस्ट (पहचान जानकारी) होती है। मौजूदा इंस्टॉलर (MSI, Inno Setup आदि) से सामान्य तरीके से इंस्टॉल हुए ऐप के लिए आप Add-AppxPackage -ExternalLocation से इंस्टॉल फ़ोल्डर की ओर इशारा करके पंजीकृत करते हैं, और ऐप पैकेज पहचान पाता है तथा Windows 11 नए कॉन्टेक्स्ट मेनू पर पंजीकरण और टोस्ट नोटिफिकेशन जैसी पहचान-आवश्यक सुविधाएँ इस्तेमाल कर सकता है। Windows 10 संस्करण 2004 से उपलब्ध है, और पैकेज को लक्ष्य मशीन पर विश्वसनीय कोड हस्ताक्षर चाहिए। जब पूरा वितरण तरीका MSIX पर न ले जाकर नए मेनू का समर्थन चाहिए, यही व्यावहारिक विकल्प है।
- कॉन्टेक्स्ट-मेनू आइटम दो बार दिखे या हटे नहीं तो क्या करें?
- पहले कारण अलग करें: वह नए मेनू पर दिखता है या पुराने पर (अधिक विकल्प दिखाएँ)। विशिष्ट दोहरी प्रदर्शन यह है कि क्लासिक रजिस्ट्री पंजीकरण और MSIX मैनिफ़ेस्ट पंजीकरण साथ-साथ हैं, या अनइंस्टॉल पर ProgID या एक्सटेंशन CLSID पंजीकरण रह गया। असोसिएशन बदलने के बाद SHChangeNotify(SHCNE_ASSOCCHANGED) छूटने का भी संदेह करें; पैकेज पंजीकरण के तुरंत बाद एक्सप्लोरर रीस्टार्ट छूटने का। फिर भी न सुलझे तो ShellExView में गैर-Microsoft एक्सटेंशन अस्थायी रूप से बंद करें और बाइनरी खोज से दोषी DLL पहचानें।