2008-10-12 21 views
68

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

उत्तर

72

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

<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% काम नहीं किया। यह फ़ाइलों को हटा दिया, हालांकि स्थापना के बाद बनाए गए अतिरिक्त निर्देशिकाओं में से कोई भी हटा दिया गया था। उस पर कोई विचार? - pribeiro

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

+1

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

+0

ओह, न तो उन निर्देशिकाओं के अंतर्गत फ़ाइलों को हटा दिया गया था। – pribeiro

+2

मैंने आपके प्रश्न का समाधान करने के लिए अपना उत्तर अपडेट किया। –

12

ऐसा करने के लिए, मैंने बस अनइंस्टॉल करने के लिए एक कस्टम कार्रवाई की है।

WiX कोड इस तरह दिखेगा:

<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 
8

नहीं एक WIX विशेषज्ञ है, लेकिन एक संभव (सरल?) इस का हल Quiet Execution Custom Action चलाने के लिए जो WIX की एक्सटेंशन में बनाया का हिस्सा है हो सकता है?

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

<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 संशोधित करने के लिए होगा।

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

+0

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

+1

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

26

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

+0

चेतावनी: RemoveFolderEx = "अनइंस्टॉल करें" पर उपयोग करते समय, यह अपग्रेड पर फ़ोल्डर को भी हटा देता है (विक्स 3.9)। 'RemoveFile' और 'RemoveFolder' पर वही व्यवहार। यदि आप फ़ाइलों को अपग्रेड पर रखना चाहते हैं, तो आप इन सभी दृष्टिकोणों का उपयोग नहीं कर सकते हैं। – Simon

+0

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

+0

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

7

यहां @ ट्रोंडा के सुझाव पर एक भिन्नता है। मैं एक फाइल को हटा रहा हूं "इंस्टॉल करें।लॉग ऑन "एक और कस्टम क्रिया के द्वारा बनाई गई हो जाता है कि, स्थापना रद्द दौरान:

<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 "क्योंकि इस फ़ाइल को स्थापना के बाद बनाई गई है, और एक घटक का हिस्सा नहीं है । समूह

+1

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

+0

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

+0

ग्रेट समाधान। धन्यवाद! –

1

यह @Pavel सुझाव के लिए एक और अधिक पूरा जवाब होगा मेरे लिए यह 100% काम कर रहा है:

<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 और रजिस्ट्री फ़ोल्डर दोनों हटा दिए जाते हैं। ध्यान दें कि रजिस्ट्री का मार्ग अन्य छिद्र और अन्य स्थानों पर हो सकता है।

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