एक वाईएक्स कस्टम एक्शन कैसे जोड़ें जो केवल अनइंस्टॉल (एमएसआई के माध्यम से) पर होता है?


161

मैं पूरी निर्देशिका को अनइंस्टॉल करने के लिए एक MSI इंस्टॉलर ( वाईएक्स के माध्यम से निर्मित ) को संशोधित करना चाहूंगा ।

मैं समझता हूँ RemoveFileऔर RemoveFolderWiX में विकल्प है, लेकिन इन रिकर्सिवली स्थापना के बाद बनाई गई सामग्री है कि एक संपूर्ण फ़ोल्डर को हटाने के लिए मजबूत पर्याप्त नहीं हैं।

मैंने ऐसा ही स्टैक ओवरफ्लो प्रश्न देखा जब वाईएक्स को अनइंस्टॉल करते समय फ़ाइलों को हटाना , लेकिन मैं सोच रहा था कि क्या फ़ोल्डर को हटाने के लिए बैच स्क्रिप्ट का उपयोग करके इसे और अधिक किया जा सकता है।

यह वाईएक्स का उपयोग करने का मेरा पहला मौका है, और मैं अभी भी कस्टम क्रियाओं को लटका रहा हूं । एक कस्टम एक्शन का मूल उदाहरण क्या होगा जो अनइंस्टॉल पर बैच स्क्रिप्ट चलाएगा?

जवाबों:


188

संपादित करें : शायद नीचे दिए गए उत्तर को तुरंत देखें


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

वैकल्पिक शब्द

इसलिए मेरे मामले में मैं एक सीए चाहता था जो केवल अनइंस्टॉल पर चलेगा - अपग्रेड नहीं, मरम्मत या संशोधन नहीं। ऊपर दी गई तालिका के अनुसार मुझे उपयोग करना था

<Custom Action='CA_ID' Before='other_CA_ID'>
        (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>

और यह काम किया!


25
क्या उस चार्ट में मूल्य सही हैं? आपको REMOVE = "ALL" जोड़ने की आवश्यकता क्यों होगी? नहीं UPGRADINGPRODUCTCODE केवल एक अनइंस्टॉल के लिए सही है (चार्ट के अनुसार), इसलिए (नहीं UPGRADINGPRODUCTCODE) और (REMOVE = "ALL") भी केवल अनइंस्टॉल पर ही सही होगा। REMOVE = "सभी" अनावश्यक लगता है।
टॉड रोपोग

2
मैं @ToddRopog से सहमत हूं - उदाहरण और सत्य तालिका से सहमत नहीं लगते। क्या यह वास्तव में सही है?
टिम लॉन्ग

19
सत्य तालिका थोड़ी गलत है। नहीं UPGRADINGPRODUCTCODE सच पहली बार एक स्थापित के लिए भी है
नील

2
सामान्य स्थितियाँ: alekdavis.blogspot.ru/2013/05/…
KindDragon

1
कृपया पुष्टि करें: स्थापित और स्थापित अलग-अलग चीजें हैं, केवल स्थापित विंडोज इंस्टालर द्वारा स्थापित है। मुझे नहीं लगता कि INSTALLED काम करता है।
मीका विडेनमैन

140

यलूना के उत्तर के साथ कई समस्याएं हैं , संपत्ति के नाम भी मामले में संवेदनशील हैं, Installedसही वर्तनी है ( INSTALLEDकाम नहीं करेगा)। उपरोक्त तालिका यह होनी चाहिए:

यहां छवि विवरण दर्ज करें

सम्पूर्ण मरम्मत और संपत्तियों की वास्तविक मूल्यों की स्थापना रद्द करना भी मान सकते हैं:

यहां छवि विवरण दर्ज करें

WiX अभिव्यक्ति सिंटेक्स प्रलेखन का कहना है:

इन अभिव्यक्तियों में, आप संपत्ति के नाम का उपयोग कर सकते हैं (याद रखें कि वे संवेदनशील हैं)।

गुण Windows इंस्टालर गाइड (जैसे स्थापित ) पर प्रलेखित हैं

संपादित करें: पहली तालिका में छोटा सुधार; जाहिर है "अनइंस्टॉल करें" भी बस के साथ हो सकता REMOVEकिया जा रहा है True



2
'अपग्रेड' कॉलम, यह है कि पुराने संस्करण की स्थापना रद्द करने या नए संस्करण के इंस्टॉल अनुक्रम के दौरान?
निक व्हले

1
@NickWhaley: मैंने कुछ समय तक इस पर ध्यान नहीं दिया, लेकिन मेरा मानना ​​है कि "अपग्रेड" विकल्प केवल तभी है जब पहले से इंस्टॉल किए गए संस्करण से अधिक संस्करण स्थापित किया गया हो।
ahmd0

1
@ ahmd0, बेशक। लेकिन एक नेस्टेड इंस्टॉलेशन है जो RemoveExistingProducts के भीतर होता है जिसमें गुणों का एक बिल्कुल अलग सेट होता है। वही आपके 'अपग्रेड' कॉलम में है। बाकी अपग्रेड 'इंस्टॉल' कॉलम के समान है।
निक व्हेल

1
@NickWhaley: REMOVE विकल्प पिछले संस्करण के अनइंस्टालर के निष्पादन के दौरान मेजर अपग्रेड्स के लिए सही होगा, अर्थात 1.0.0 से 2.0.0, नहीं 1.0.0 से 1.1.0। नए संस्करणों को स्थापित करने में एक मेजर अपग्रेड के दौरान एक कस्टम एक्शन चलाने के लिए आपको उस संस्करण के उन्नयन के लिए अपने अपग्रेड MSI तालिका में परिभाषित ActionProperty को संदर्भित करना होगा। symantec.com/connect/articles/msi-upgrad-overview msdn.microsoft.com/en-us/library/aa372379%28v=vs.85%29.aspx
Chaoix

48

आप एक कस्टम एक्शन के साथ ऐसा कर सकते हैं। आप अपने कस्टम एक्शन के तहत एक फेरबदल जोड़ सकते हैं <InstallExecuteSequence>:

<InstallExecuteSequence>
...
  <Custom Action="FileCleaner" After='InstallFinalize'>
          Installed AND NOT UPGRADINGPRODUCTCODE</Custom>

फिर आपको अपनी कार्रवाई को <Product>निम्न प्रकार से परिभाषित करना होगा :

<Product> 
...
  <CustomAction Id='FileCleaner' BinaryKey='FileCleanerEXE' 
                ExeCommand='' Return='asyncNoWait'  />

जहां FileCleanerEXE एक द्विआधारी है (मेरे मामले में थोड़ा सी ++ प्रोग्राम जो कस्टम क्रिया करता है) जो कि नीचे भी परिभाषित है <Product>:

<Product> 
...
  <Binary Id="FileCleanerEXE" SourceFile="path\to\fileCleaner.exe" />

इसके लिए वास्तविक चाल Installed AND NOT UPGRADINGPRODUCTCODEकस्टम क्रिया पर स्थिति है, जिसके साथ आपकी कार्रवाई हर अपग्रेड पर चलेगी (चूंकि अपग्रेड वास्तव में अनइंस्टॉल है तो पुनः इंस्टॉल करें)। यदि आप फ़ाइलों को हटा रहे हैं, तो शायद आप अपग्रेड के दौरान नहीं चाहते हैं।

एक साइड नोट पर: मैं सी + + प्रोग्राम जैसी किसी चीज का उपयोग करने की परेशानी से गुजरने की सलाह देता हूं, क्योंकि यह एक बैच स्क्रिप्ट के बजाय शक्ति और नियंत्रण प्रदान करता है - और आप "cmd प्रॉम्प्ट" विंडो को फ्लैश होने से रोक सकते हैं आपका इंस्टॉलर चलता है।


3
25 उत्थान लेकिन एक स्वीकृत उत्तर नहीं। इंस्टॉलर की दुनिया में आपका स्वागत है! :)
क्रिस्टोफर पेंटर

4
यह वास्तव में काम नहीं करता है। जब आप किसी fileCleaner.exe को निष्पादित करना चाहते हैं, जो आपके अपने स्थापना फ़ोल्डर में स्थापित है, तो यह चिकन-एंड-एग समस्या CustomActionहोगी : "After = 'InstallFinalize' निष्पादित किया जाएगा।" इस बिंदु पर, सभी फ़ाइलों को स्थापना फ़ोल्डर से हटा दिया जाता है। इसके अलावा fileCleaner.exe। तो आप एक CustomAction के माध्यम से इसे निष्पादित करने में सक्षम नहीं हैं। यह उत्तर केवल गलत है। मैं 42 upvotes के बारे में सोच रहा हूँ!
साइमन

40

बैच स्क्रिप्ट के साथ सबसे बड़ी समस्या रोलबैक को संभालना है जब उपयोगकर्ता क्लिक को रद्द करता है (या आपके इंस्टॉल के दौरान कुछ गलत हो जाता है)। इस परिदृश्य को संभालने का सही तरीका एक कस्टमएशन बनाना है जो RemoveFiles टेबल में अस्थायी पंक्तियों को जोड़ता है। इस तरह से विंडोज इंस्टॉलर आपके लिए रोलबैक मामलों को संभालता है। जब आप समाधान देखते हैं तो यह बहुत सरल है।

वैसे भी, स्थापना रद्द करने के दौरान केवल एक एक्शन एलिमेंट जोड़ने के लिए एक्शन एलिमेंट:

REMOVE ~= "ALL"

~ = का कहना है कि मामले की असंवेदनशीलता की तुलना करें (भले ही मुझे लगता है कि सभी हमेशा ऊपरी है)। अधिक जानकारी के लिए शर्तों सिंटैक्स के बारे में एमएसआई एसडीके प्रलेखन देखें।

पुनश्च: ऐसा कोई मामला नहीं है जहां मैं बैठ गया और सोचा, "ओह, बैच फ़ाइल एक इंस्टॉलेशन पैकेज में एक अच्छा समाधान होगा।" वास्तव में, एक इंस्टॉलेशन पैकेज ढूंढना, जिसमें एक बैच फ़ाइल है, केवल मुझे रिफंड के लिए उत्पाद वापस करने के लिए प्रोत्साहित करेगा।


मैं एक बैच स्क्रिप्ट का उपयोग करने वाला था और फिर PS अनुभाग को देखा। मुझे बचाने के लिए धन्यवाद:) मेरे लिए काम ~ ~ "सभी" निकालें।
अरनंब

12

यहाँ उन गुणों का एक सेट है जो मैंने बनाया है जो निर्मित सामानों की तुलना में उपयोग करने के लिए अधिक सहज महसूस करते हैं। शर्तें ahmd0 द्वारा ऊपर दी गई सत्य तालिका से बाहर हैं।

<!-- truth table for installer varables (install vs uninstall vs repair vs upgrade) https://stackoverflow.com/a/17608049/1721136 -->
 <SetProperty Id="_INSTALL"   After="FindRelatedProducts" Value="1"><![CDATA[Installed="" AND PREVIOUSVERSIONSINSTALLED=""]]></SetProperty>
 <SetProperty Id="_UNINSTALL" After="FindRelatedProducts" Value="1"><![CDATA[PREVIOUSVERSIONSINSTALLED="" AND REMOVE="ALL"]]></SetProperty>
 <SetProperty Id="_CHANGE"    After="FindRelatedProducts" Value="1"><![CDATA[Installed<>"" AND REINSTALL="" AND PREVIOUSVERSIONSINSTALLED<>"" AND REMOVE=""]]></SetProperty>
 <SetProperty Id="_REPAIR"    After="FindRelatedProducts" Value="1"><![CDATA[REINSTALL<>""]]></SetProperty>
 <SetProperty Id="_UPGRADE"   After="FindRelatedProducts" Value="1"><![CDATA[PREVIOUSVERSIONSINSTALLED<>"" ]]></SetProperty>

यहाँ कुछ नमूना उपयोग है:

  <Custom Action="CaptureExistingLocalSettingsValues" After="InstallInitialize">NOT _UNINSTALL</Custom>
  <Custom Action="GetConfigXmlToPersistFromCmdLineArgs" After="InstallInitialize">_INSTALL OR _UPGRADE</Custom>
  <Custom Action="ForgetProperties" Before="InstallFinalize">_UNINSTALL OR _UPGRADE</Custom>
  <Custom Action="SetInstallCustomConfigSettingsArgs" Before="InstallCustomConfigSettings">NOT _UNINSTALL</Custom>
  <Custom Action="InstallCustomConfigSettings" Before="InstallFinalize">NOT _UNINSTALL</Custom>

मुद्दे:

  • UPGRADINGPRODUCTCODE को RemoveExistingProducts क्रिया के दौरान सेट किया जाता है, इसलिए आपके द्वारा पूर्व में चलाई जाने वाली कोई भी कस्टम क्रिया यह नहीं जानती है कि यह एक उन्नयन है https://docs.microsoft.com/en-us/windows/desktop/Msi-upmissionproductcode

यह एक बेहतरीन उपाय है। याद रखें कि PATCH और MSIPATCHREMOVE शर्तों पर भी विचार करें।
गेरेट जैक्स

अपनी सत्य तालिका में, क्या आपका मतलब UPGRADINGPRODUCTCODE के बजाय PREVIOUSVERSIONSINSTALLED का उपयोग करना है जैसा कि ahmd0 द्वारा उपयोग किया जाता है? मैं MSI प्रॉपर्टी रेफरेंस पेज ( docs.microsoft.com/en-us/windows/win32/msi/property-reference ) पर PREVIOUSVERSIONSINSTALLED का कोई संदर्भ नहीं देख रहा हूं ।
पैट्रिक

आपके गुणों के लिए कई विधेयकों को ahmd0 की तालिका की सभी पंक्तियों (इंस्टॉल, REINSTALL, UPGRADINGPRODUCTCODE और REMOVE) पर ध्यान नहीं दिया जाता है। क्या आप कृपया बताएंगे कि क्यों?
पैट्रिक

0

मैंने C ++ DLL में कस्टम एक्शन को अलग से कोड किया और इस सिंटैक्स का उपयोग करके अनइंस्टॉलिंग पर उपयुक्त फ़ंक्शन को कॉल करने के लिए DLL का उपयोग किया:

<CustomAction Id="Uninstall" BinaryKey="Dll_Name" 
              DllEntry="Function_Name" Execute="deferred" />

उपरोक्त कोड ब्लॉक का उपयोग करके, मैं C ++ DLL में परिभाषित किसी भी फ़ंक्शन को अनइंस्टॉल करने में सक्षम था। FYI करें, मेरे अनइंस्टॉल फ़ंक्शन में वर्तमान उपयोगकर्ता डेटा और रजिस्ट्री प्रविष्टियों को साफ़ करने के बारे में कोड था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.