वाईएक्स की स्थापना रद्द करते समय फ़ाइलों को हटाना


84

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

जवाबों:


83

On = " अनइंस्टॉल " के साथ RemoveFile तत्व का उपयोग करें । यहाँ एक उदाहरण है:

<Directory Id="CommonAppDataFolder" Name="CommonAppDataFolder">
  <Directory Id="MyAppFolder" Name="My">
    <Component Id="MyAppFolder" Guid="*">
      <CreateFolder />
      <RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
    </Component>
  </Directory>
</Directory>

अपडेट करें

यह 100% काम नहीं किया। यह फ़ाइलों को हटा दिया, हालांकि स्थापना के बाद बनाई गई अतिरिक्त निर्देशिकाओं में से कोई भी - हटा दी गई थी। उस पर कोई विचार? - पुरबीरो

दुर्भाग्य से विंडोज इंस्टॉलर उपनिर्देशिकाओं के साथ निर्देशिकाओं को हटाने का समर्थन नहीं करता है। इस मामले में आपको कस्टम एक्शन का सहारा लेना होगा। या, यदि आप जानते हैं कि सबफ़ोल्डर्स क्या हैं, तो RemoveFolder और RemoveFile तत्वों का एक गुच्छा बनाएं।


1
धन्यवाद पावेल हालांकि यह 100% काम नहीं किया। यह फ़ाइलों को हटा दिया, हालांकि स्थापना के बाद बनाई गई अतिरिक्त निर्देशिकाओं में से कोई भी - हटा दी गई थी। उस पर कोई विचार?
प्रिबेइरो

ओह, न तो उन निर्देशिकाओं के तहत फ़ाइलें हटा दी गईं।
प्रिबेइरो

जब आप मेजर अपग्रेड्स पर 'MyAppFolder' में फाइल्स (उदाहरण के लिए कॉन्फिग फाइल्स) रखेंगे, तो आपको इस अप्रोच की समस्या होगी। सभी फ़ाइलों को एक अपग्रेड द्वारा हटा दिया जाएगा।
साइमन

1
क्या MyAppFolder में डायरेक्टरी बनाने के लिए आपके कोड के साथ संभव है? जब मैं </Component>एक संकलन जोड़ने के बाद एक निर्देशिका में विफल रहा हूँFound orphaned Component 'MyAppFolder'.
A.Pissicat

2
@PhilipRego कॉमनऐपडेटाफोल्डर डोक्यूमनेशन के लिए msdn.microsoft.com/en-us/library/windows/desktop/aa367992.aspx देखें ।
पावेल चुचुवा

30

RemoveFolderExवाईएक्स में यूटिल एक्सटेंशन से तत्व का उपयोग करें ।
इस दृष्टिकोण के साथ, सभी उपनिर्देशिकाएं भी हटा दी जाती हैं ( सीधे तत्व का उपयोगRemoveFile करने के विपरीत )। यह तत्व MSI डेटाबेस में अस्थायी पंक्तियों को RemoveFileऔर RemoveFolderतालिका में जोड़ता है।


2
चेतावनी: जब RemoveFolderEx ऑन = "अनइंस्टॉल" का उपयोग करते हुए, यह एक अपग्रेड (Wix 3.9) पर फ़ोल्डर को भी हटा देता है। पर RemoveFileऔर समान व्यवहार RemoveFolder। यदि आप फ़ाइलों को अपग्रेड पर रखना चाहते हैं, तो आप इन सभी तरीकों का उपयोग नहीं कर सकते।
साइमन

@ साइमन क्या दृष्टिकोण सुझाएगा यदि आप फाइलों को अपग्रेड पर रखना चाहते हैं?
बिंगटन

@ बीजिंग: जब आप अपने इंस्टालेशन फोल्डर में विशिष्ट फ़ाइलों को अपग्रेड पर रखना चाहते हैं, तो एक कस्टम एक्शन का उपयोग करें जो कस्टम कोड (जैसे c # लिखा हुआ हैंडलेसेटअप। Exe) निष्पादित करता है। कस्टम कोड आपकी फ़ाइलों को इंस्टॉल पर वितरित करता है, आपकी फ़ाइलों को अपग्रेड पर रखता है और फ़ाइलों को अनइंस्टॉल पर हटा देता है।
साइमन

@ धन्यवाद धन्यवाद, मुझे उस दृष्टिकोण पर ध्यान देना पड़ सकता है, हालांकि यह वर्तमान में काम कर रहा है: stackoverflow.com/a/21383113/32348
Bijington

13

ऐसा करने के लिए, मैंने बस एक कस्टम कार्रवाई की स्थापना रद्द करने के लिए बुलाया।

वाईएक्स कोड इस तरह दिखेगा:

<Binary Id="InstallUtil" src="InstallUtilLib.dll" />

<CustomAction Id="DIRCA_TARGETDIR" Return="check" Execute="firstSequence" Property="TARGETDIR" Value="[ProgramFilesFolder][Manufacturer]\[ProductName]" />
<CustomAction Id="Uninstall" BinaryKey="InstallUtil" DllEntry="ManagedInstall" Execute="deferred" />
<CustomAction Id="UninstallSetProp" Property="Uninstall" Value="/installtype=notransaction /action=uninstall /LogFile= /targetDir=&quot;[TARGETDIR]\Bin&quot; &quot;[#InstallerCustomActionsDLL]&quot; &quot;[#InstallerCustomActionsDLLCONFIG]&quot;" />

<Directory Id="BinFolder" Name="Bin" >
    <Component Id="InstallerCustomActions" Guid="*">
        <File Id="InstallerCustomActionsDLL" Name="SetupCA.dll" LongName="InstallerCustomActions.dll" src="InstallerCustomActions.dll" Vital="yes" KeyPath="yes" DiskId="1" Compressed="no" />
        <File Id="InstallerCustomActionsDLLCONFIG" Name="SetupCA.con" LongName="InstallerCustomActions.dll.Config" src="InstallerCustomActions.dll.Config" Vital="yes" DiskId="1" />
    </Component>
</Directory>

<Feature Id="Complete" Level="1" ConfigurableDirectory="TARGETDIR">
    <ComponentRef Id="InstallerCustomActions" />
</Feature>

<InstallExecuteSequence>
    <Custom Action="UninstallSetProp" After="MsiUnpublishAssemblies">$InstallerCustomActions=2</Custom>
    <Custom Action="Uninstall" After="UninstallSetProp">$InstallerCustomActions=2</Custom>
</InstallExecuteSequence>

InstallerCustomActions.DLL में OnBeforeUninstall विधि का कोड इस तरह दिखाई देगा (VB में)।

Protected Overrides Sub OnBeforeUninstall(ByVal savedState As System.Collections.IDictionary)
    MyBase.OnBeforeUninstall(savedState)

    Try
        Dim CommonAppData As String = Me.Context.Parameters("CommonAppData")
        If CommonAppData.StartsWith("\") And Not CommonAppData.StartsWith("\\") Then
            CommonAppData = "\" + CommonAppData
        End If
        Dim targetDir As String = Me.Context.Parameters("targetDir")
        If targetDir.StartsWith("\") And Not targetDir.StartsWith("\\") Then
            targetDir = "\" + targetDir
        End If

        DeleteFile("<filename.extension>", targetDir) 'delete from bin directory
        DeleteDirectory("*.*", "<DirectoryName>") 'delete any extra directories created by program
    Catch
    End Try
End Sub

Private Sub DeleteFile(ByVal searchPattern As String, ByVal deleteDir As String)
    Try
        For Each fileName As String In Directory.GetFiles(deleteDir, searchPattern)
            File.Delete(fileName)
        Next
    Catch
    End Try
End Sub

Private Sub DeleteDirectory(ByVal searchPattern As String, ByVal deleteDir As String)
    Try
        For Each dirName As String In Directory.GetDirectories(deleteDir, searchPattern)
            Directory.Delete(dirName)
        Next
    Catch
    End Try
End Sub

11

यहाँ @ ट्रोनडा के सुझाव पर भिन्नता है। मैं एक फ़ाइल "install.log" हटा रहा हूं जो अनइंस्टॉल के दौरान एक और कस्टम एक्शन द्वारा बनाई गई है:

<Product>
    <CustomAction Id="Cleanup_logfile" Directory="INSTALLFOLDER"
    ExeCommand="cmd /C &quot;del install.log&quot;"
    Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action="Cleanup_logfile" Before="RemoveFiles" >
        REMOVE="ALL"
      </Custom>
    </InstallExecuteSequence>
</Product>

जहां तक ​​मैं समझता हूं, मैं "RemoveFile" का उपयोग नहीं कर सकता क्योंकि यह फ़ाइल स्थापना के बाद बनाई गई है, और घटक समूह का हिस्सा नहीं है।


4
मैंने पूरी निर्देशिका को हटाने के लिए कुछ बदलावों के साथ इस समाधान का उपयोग किया: ExeCommand = "cmd / C RD & quot; [INSTALLFOLDER] & quot; / s / q"
डेनिस

@ डेनिस INSTALLFOLDER को कैसे हटाएं, 10 जीतने पर यह डिलीट हो जाता है लेकिन विंडोज सर्वर 2012 में ऐसा नहीं होता है।
eomeroff

महान समाधान। धन्यवाद!
यूरी कोमारनीत्स्की

मैंने कई चीजों की कोशिश की - कोई यह नहीं सोचेगा कि अनइंस्टॉल के दौरान एक भी फाइल को हटाना मुश्किल हो सकता है। हालांकि यह मेरे लिए काम किया - धन्यवाद!
लकी ल्यूक

7

यह मेरे लिए 100% काम कर रहा है, @Pavel सुझाव के लिए एक और अधिक पूर्ण उत्तर होगा :

<Fragment Id="FolderUninstall">
    <?define RegDir="SYSTEM\ControlSet001\services\[Manufacturer]:[ProductName]"?>
    <?define RegValueName="InstallDir"?>
    <Property Id="INSTALLFOLDER">
        <RegistrySearch Root="HKLM" Key="$(var.RegDir)" Type="raw" 
                  Id="APPLICATIONFOLDER_REGSEARCH" Name="$(var.RegValueName)" />
    </Property>

    <DirectoryRef Id='INSTALLFOLDER'>
        <Component Id="UninstallFolder" Guid="*">
            <CreateFolder Directory="INSTALLFOLDER"/>
            <util:RemoveFolderEx Property="INSTALLFOLDER" On="uninstall"/>
            <RemoveFolder Id="INSTALLFOLDER" On="uninstall"/>
            <RegistryValue Root="HKLM" Key="$(var.RegDir)" Name="$(var.RegValueName)" 
                    Type="string" Value="[INSTALLFOLDER]" KeyPath="yes"/>
        </Component>
    </DirectoryRef>
</Fragment>

और, उत्पाद तत्व के तहत:

<Feature Id="Uninstall">
    <ComponentRef Id="UninstallFolder" Primary="yes"/>
</Feature>

यह दृष्टिकोण स्थापना रद्द करने के लिए फ़ोल्डर के वांछित पथ के साथ एक रजिस्ट्री मान सेट करता है। अंत में, सिस्टम से INSTALLFOLDER और रजिस्ट्री फ़ोल्डर दोनों को हटा दिया जाता है। ध्यान दें कि रजिस्ट्री का पथ अन्य हाइव और अन्य स्थानों पर हो सकता है।


6

एक आगंतुक विशेषज्ञ नहीं है, लेकिन यह संभव (सरल?) समाधान हो सकता है कि वह शांत निष्पादन कस्टम क्रिया को चला सके जो कि आगंतुक के एक्सटेंशन में निर्मित हिस्सा है?

चला सकते हैं rmdir / एस और / Q विकल्पों के साथ एमएस डॉस कमांड।

<Binary Id="CommandPrompt" SourceFile="C:\Windows\System32\cmd.exe" />

और कार्य करने वाली कस्टम क्रिया सरल है:

<CustomAction Id="DeleteFolder" BinaryKey="CommandPrompt" 
              ExeCommand='/c rmdir /S /Q "[CommonAppDataFolder]MyAppFolder\PurgeAppFolder"' 
              Execute="immediate" Return="check" />

फिर आपको कई स्थानों पर प्रलेखित InstallExecuteSequence को संशोधित करना होगा।

अद्यतन: इस दृष्टिकोण के साथ मुद्दों था। इसके बजाय एक कस्टम कार्य करना समाप्त किया, लेकिन अभी भी यह एक व्यवहार्य समाधान मानता है, लेकिन काम करने के लिए विवरण प्राप्त किए बिना।


मुझे यह विकल्प पसंद है तथ्य यह है कि आप इंस्टॉलर में cmd.exe शामिल कर रहे हैं। निश्चित रूप से हर मशीन में यह होगा, आपको इसे खोजने के लिए बस एक DirectorySearch का उपयोग करना होगा! :)
caveman_dick

4
यह मत करो। 1) आप cmd.exeअपने इंस्टॉलर में एम्बेड कर रहे हैं । 2) आप स्क्रिप्ट निर्माण के दौरान सिस्टम में परिवर्तन कर रहे हैं 3) कोई रोलबैक विकल्प नहीं है 4) लॉक की गई फ़ाइलों के साथ सही ढंग से व्यवहार नहीं करता है
निक व्हेल

मुझे संदेह है कि विंडोज इंस्टॉलेशन से फाइल वितरित करना कानूनी है। यह भी स्पष्ट नहीं है कि यह लक्ष्य प्रणाली पर काम करेगा जो विंडोज का एक अलग संस्करण चला सकता है।
पॉल बी।

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