इनो सेटअप: स्वचालित रूप से पिछले स्थापित संस्करण की स्थापना रद्द कैसे करें?


88

मैं एक इंस्टॉलर बनाने के लिए इनो सेटअप का उपयोग कर रहा हूं।

मैं चाहता हूं कि इंस्टॉलर इसे अधिलेखित करने के बजाय पिछले स्थापित संस्करण को स्वचालित रूप से अनइंस्टॉल कर दे। मैं उसे कैसे कर सकता हूँ?


2
ध्यान दें कि जैसा कि मल्लन ने कहा कि आम तौर पर इनो आधारित सेटअप के साथ ऐसा करने की कोई आवश्यकता नहीं है जब तक कि आप एक गैर इनो संस्करण से अपग्रेड नहीं करते हैं।
डीनना

7
डीनना: यह केस पर निर्भर करता है। स्वचालित प्लगइन सिस्टम के साथ कुछ कार्यक्रमों के लिए, जो एक फ़ोल्डर में कुछ भी पढ़ते हैं, पुरानी फ़ाइलों को हटाना एक नया संस्करण स्थापित करते समय एक पूर्ण होना चाहिए, और बस अनइंस्टॉल चलाना आमतौर पर ऐसा करने का सबसे साफ तरीका है।
Nyerguds 7

1
@Nyerguds लेकिन InnoSetup स्थापना प्रारंभ होने से पहले कुछ फ़ाइलों / फ़ोल्डरों को हटाने का विकल्प होने के कारण पूरा करता है ("InstallDelete" ध्वज) तो आपको अभी भी पहले पुराने संस्करण को अनइंस्टॉल करने की आवश्यकता नहीं होगी।
निक

3
@ नाइक: फिर, मामले पर निर्भर करता है। यह आदर्श स्थिति होगी, हां, और अब तक पसंदीदा एक है, लेकिन वास्तव में, काफी गैर-आदर्श परिस्थितियां हैं। ऐसा ही एक उदाहरण कई संभावित लक्ष्य संस्करणों पर पंजीकृत dll फाइलें हैं।
Nyerguds

जवाबों:


27

आपको AppId (यानी -section AppIDमें आपके द्वारा उपयोग किया जाने वाला मूल्य [Setup]) को देखते हुए, आपको रजिस्ट्री से अनइंस्टॉल स्ट्रिंग पढ़ने में सक्षम होना चाहिए । इसके तहत पाया जा सकता है Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\( HKLMया तो हो सकता है या HKCU, इसलिए दोनों की सर्वोत्तम जांच करें) जहां {AppId}आपके द्वारा उपयोग किए गए वास्तविक मूल्य के साथ प्रतिस्थापित किया जाना चाहिए। के लिए देखो UninstallStringया QuietUninstallStringमूल्यों और का उपयोग Execअपने से इसे चलाने के लिए समारोह InitializeSetup()घटना कार्य करते हैं।

अद्यतन: गैर-काम कर रहे वैकल्पिक समाधान के [Run]साथ -section प्रविष्टि का उपयोग करके हटा दिया गया {uninstallexe}- उन सभी टिप्पणीकारों को धन्यवाद जिन्होंने इसे इंगित किया था!


+1, लेकिन पुराने अनइंस्टालर नाम को पढ़ने के लिए निश्चित रूप से स्क्रिप्टिंग का उपयोग करें, क्योंकि अन्यथा यह काम नहीं करेगा यदि उपयोगकर्ता द्वारा एक अलग पथ दर्ज किया गया है।
5

3
मुझे नहीं लगता कि [Run]अनुभाग समाधान काम करेगा, क्योंकि यह स्थापना प्रक्रिया में बहुत देर से चलता है। इनो सेटअप मैनुअल से: [रन] अनुभाग वैकल्पिक है, और प्रोग्राम को सफलतापूर्वक इंस्टॉल किए जाने के बाद निष्पादित करने के लिए किसी भी संख्या को निर्दिष्ट करता है, लेकिन सेटअप प्रोग्राम अंतिम संवाद प्रदर्शित करने से पहले।
क्रेग मैक्वीन

कृपया इस पोस्ट को संपादित करें और [रन] भाग को हटा दें, यह काम नहीं करता है। दूसरा भाग हालांकि काम करता है। धन्यवाद :-)
Saulius itaemaitaitis

11
एक चेतावनी: 64 बिट विंडोज पर एक 32 बिट एप्लिकेशन के लिए, पथ `सॉफ्टवेयर \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall \ {AppId} हो सकता है
एड्रियन कॉक्स

4
@ एड्रियन: जबकि यह अच्छी तरह से भौतिक परत पर सही हो सकता है, मुझे लगता है कि इनो द्वारा उपयोग की जाने वाली WinAPI- कॉल पहले से ही इस बात का ध्यान रखेगी - कम से कम अगर setup.exe स्वयं एक 32 बिट प्रक्रिया है।
ओलिवर गिसेन

112

मैंने निम्नलिखित का उपयोग किया है। मुझे यकीन नहीं है कि यह करने का सबसे सरल तरीका है लेकिन यह काम करता है।

यह उपयोग {#emit SetupSetting("AppId")}जो इनो सेटअप प्रीप्रोसेसर पर निर्भर करता है। यदि आप इसका उपयोग नहीं करते हैं, तो सीधे अपनी ऐप आईडी को काटें और चिपकाएँ।

[Code]

{ ///////////////////////////////////////////////////////////////////// }
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;


{ ///////////////////////////////////////////////////////////////////// }
function IsUpgrade(): Boolean;
begin
  Result := (GetUninstallString() <> '');
end;


{ ///////////////////////////////////////////////////////////////////// }
function UnInstallOldVersion(): Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
{ Return Values: }
{ 1 - uninstall string is empty }
{ 2 - error executing the UnInstallString }
{ 3 - successfully executed the UnInstallString }

  { default return value }
  Result := 0;

  { get the uninstall string of the old app }
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end else
    Result := 1;
end;

{ ///////////////////////////////////////////////////////////////////// }
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if (CurStep=ssInstall) then
  begin
    if (IsUpgrade()) then
    begin
      UnInstallOldVersion();
    end;
  end;
end;

वैकल्पिक

इस ब्लॉग पोस्ट "संस्करण तुलना के लिए इनो सेटअप स्क्रिप्ट नमूना" भी देखें जो एक कदम आगे जाता है, और किसी भी पहले से स्थापित संस्करण के संस्करण संख्या को पढ़ता है, और उस संस्करण संख्या की तुलना वर्तमान स्थापना पैकेज से करता है।


3
मेरे ब्लॉग पोस्ट का जिक्र करने के लिए धन्यवाद। उस पोस्ट का पूरा नमूना यहाँ उपलब्ध है। code.google.com/p/lextudio/source/browse/trunk/trunk/setup/…
Lex Li

यहां केवल एक चीज गायब है, HKLM के बजाय HKCU के तहत अनइंस्टॉल-एंट्री के लिए समर्थन है।
ओलिवर गिसेन

1
यदि किसी उपयोगकर्ता ने एप्लिकेशन इंस्टॉल किया है, तो मैं अनइंस्टॉल करने की क्षमता जोड़ने का सुझाव दे सकता हूं, खासकर अगर वर्तमान उपयोगकर्ता एक प्रशासक है? ... UserSIDs: TArrayOfString; I: Integer; ... if not RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString) then if isAdminLoggedOn() and RegGetSubkeyNames( HKEY_USERS, '', UserSIDs ) then for I := 0 to GetArrayLength( UserSIDs ) - 1 do begin if RegQueryStringValue( HKEY_USERS, UserSIDs[I] + '\' + sUnInstPath, 'UninstallString', sUnInstallString ) then break; end;
टेरेंस

2
महान समाधान, ठीक काम करता है। हालांकि यह स्थापना के दौरान एक विंडो खोलता है "अनइंस्टॉलिंग [सॉफ्टवेयर नाम]" दिखा रहा है। क्या इस विंडो को पॉपिंग से रोकना संभव है? क्योंकि मेरे सॉफ़्टवेयर का इंस्टॉलेशन इतना तेज़ है कि इंस्टॉलेशन विंडो अनइंस्टॉल विंडो से पहले ही बंद हो जाती है और यह अजीब लगता है ...
André Santaló

4
@ AndréSantaló / साइलेंट की जगह / VERENTILENT का उपयोग करें
गौतम जैन

7

यदि आप "पुराने आइकन हटाना चाहते हैं" (क्योंकि आपका परिवर्तन / अद्यतन हो गया है) तो आप इसका उपयोग कर सकते हैं:

; attempt to remove previous versions' icons
[InstallDelete]
Type: filesandordirs; Name: {group}\*;

यह "इंस्टॉलेशन की शुरुआत में" चलाया जाता है, इसलिए मूल रूप से पुराने आइकन हटाता है, और आपके नए पूरी तरह से स्थापित होने के बाद भी वहां स्थापित किए जाएंगे।

मैं बस हर इंस्टॉल के साथ ऐसा करता हूं "अगर कुछ भी बदल गया है" आइकन वार (यह सब वैसे भी फिर से इंस्टॉल हो जाता है)।


यदि आपके पास अपने आइकन के लिए अपडेट है, तो बस उन्हें अधिलेखित कर दें। उन्हें हटाने की कोई आवश्यकता नहीं है। ठीक है, यदि आप उन्हें निकालना चाहते हैं, तो आप इस विकल्प का उपयोग कर सकते हैं। यह सही तरीका है। वैसे भी, आप जिस आदमी से बात कर रहे थे (मल्लन, मार्टिज़न लान) इनो सेटअप लेखक हैं और मुझे लगता है कि वह जानता है कि वह किस बारे में बात कर रहा है :-)
तिलामा

1
हाँ, यह तब होता है जब आप एक आइकन का नाम बदलना या स्थानांतरित करना चाहते हैं जिसे आपको इसकी आवश्यकता है। उदाहरण के लिए यदि v5 में "रन" नाम है और v6 ने इसका नाम बदलकर "रन बेसिक" कर दिया है यदि कोई उपयोगकर्ता v5 स्थापित करता है तो v6, वे 2 आइकन के साथ समाप्त हो जाएंगे, जब आप वास्तव में 1 ("बेसिक रन" चाहते थे)। तो यह ट्रिक समाप्त होने के लिए आवश्यक है (@mlaan +1 को इनसोसेटअप के डिफ़ॉल्ट व्यवहार को बदलने के लिए पुराने आइकनों को हटाने के लिए और इस की आवश्यकता नहीं है ...)
rogerdpack

6

इनो सेटअप का उपयोग करते समय, पिछले संस्करण की स्थापना रद्द करने का कोई कारण नहीं है जब तक कि उस संस्करण को अलग इंस्टॉलर प्रोग्राम द्वारा स्थापित नहीं किया गया था। अन्यथा उन्नयन स्वचालित रूप से नियंत्रित किया जाता है।


6
हमारे कार्यक्रम को संरचना में बदलाव मिला, इसलिए पुराने संस्करण को अनइंस्टॉल करने की आवश्यकता है।
क्वान माई

11
नहीं यह नहीं है, आप एक अद्यतन के दौरान संरचना परिवर्तन को संभालने के लिए अपनी स्क्रिप्ट में प्रविष्टियाँ जोड़ सकते हैं।
मलय

@ मल्लन और वे कौन सी प्रविष्टियाँ होंगी?
मिथोफैक्लोन

1
आप [InstallDelete]पुरानी फ़ाइलों / निर्देशिकाओं को निकालने के लिए बस एक अनुभाग का उपयोग कर सकते हैं । नई फ़ाइलों को स्थापना के दौरान सही स्थानों पर रखा जाएगा।
Daiscog

2
यदि आप DevExpress जैसी किसी थर्ड पार्टी लाइब्रेरी को अपग्रेड करते हैं, जिसमें DLL नामों में संस्करण संख्याएँ होती हैं (जैसे 15.1 पहले स्थापित और अब 15.2) तो आप पुराने संस्करण को हटाना चाहते हैं। IMHO यह एक अच्छा कारण है।
और मुझे यकीन है कि मैं

2

क्रेग मैकक्वीन द्वारा प्रदान किया गया उत्तर पूरी तरह से व्यवहार्य है। हालाँकि, मैं उन टिप्पणियों को जोड़ूंगा:

  • {#emit SetupSetting("AppId")}कोड, मेरे लिए काम नहीं करता है तो मैं बस अपना ऐप्लिकेशन आईडी जोड़ें।
  • मैं अपने अनइंस्टॉलेशन प्रोग्राम को निष्पादित नहीं करना चाहता था, क्योंकि मेरे पास AppData / फ़ोल्डर में एक INI कॉन्फिगर फाइल है, जिसे अनइंस्टालर द्वारा हटा दिया गया है, और मैं नहीं चाहता कि इसे एक नया संस्करण स्थापित करते समय मिटा दिया जाए। इसलिए, मैंने क्रेग मैकक्वीन द्वारा प्रदान की गई निर्देशिका को हटाने के लिए थोड़ा सा कोड संशोधित किया, जहां कार्यक्रम को स्थापित किया गया है, इसके पथ को पुनः प्राप्त करने के बाद।

तो, क्रेग मैकक्वीन के कोड के बारे में, परिवर्तन हैं:

  • InstallLocationकुंजी के बजाय कुंजी को पुनः प्राप्त करें UninstallString
  • के DelTreeबजाय फ़ंक्शन का उपयोग करेंExec(sUnInstallString, ...)

1

किसी के लिए जो GetUninstallString()ऊपर दिए गए सुझाव का उपयोग करता है एक अनइंस्टॉल को मजबूर करने के लिए CurStepChanged()और डिस्क कैशिंग मुद्दों के लिए, संबंधित समाधान के लिए नीचे देखें जो वास्तव में अनइंस्टालर के लिए अनइंस्टाल करने के बाद थोड़ी देर इंतजार करता है जिसे हटा दिया जाना है!

मासूम सेटअप के साथ डिस्क कैशिंग मुद्दा?


0

आप [कोड] अनुभाग में एक अनइंस्टालर को निष्पादित कर सकते हैं। आपको यह पता लगाना होगा कि मौजूदा अनइंस्टालर को रास्ता कैसे मिलेगा। सादगी के लिए जब मैं अपने एप्लिकेशन इंस्टॉल करता हूं तो मैं रजिस्ट्री स्ट्रिंग मान जोड़ता हूं जो कि अनइंस्टालर वाले फ़ोल्डर को इंगित करता है, और अनइंस्टालरवेयर कॉलबैक में अनइंस्टालर को निष्पादित करता है।

ध्यान रखें कि इनो सेटअप अनइंस्टालर नाम सभी फॉर्म uninsnnn.exe के हैं, आपको अपने कोड में इसे ध्यान में रखना होगा।


0

मुझे @ Mc-रानी कोड संपादित मिला, मुझे लगता है कि यह कोड बेहतर है क्योंकि अलग-अलग परियोजना में संशोधित करने की आवश्यकता नहीं है:

[Code]
function GetNumber(var temp: String): Integer;
var
  part: String;
  pos1: Integer;
begin
  if Length(temp) = 0 then
  begin
    Result := -1;
    Exit;
  end;
    pos1 := Pos('.', temp);
    if (pos1 = 0) then
    begin
      Result := StrToInt(temp);
    temp := '';
    end
    else
    begin
    part := Copy(temp, 1, pos1 - 1);
      temp := Copy(temp, pos1 + 1, Length(temp));
      Result := StrToInt(part);
    end;
end;

function CompareInner(var temp1, temp2: String): Integer;
var
  num1, num2: Integer;
begin
    num1 := GetNumber(temp1);
  num2 := GetNumber(temp2);
  if (num1 = -1) or (num2 = -1) then
  begin
    Result := 0;
    Exit;
  end;
      if (num1 > num2) then
      begin
        Result := 1;
      end
      else if (num1 < num2) then
      begin
        Result := -1;
      end
      else
      begin
        Result := CompareInner(temp1, temp2);
      end;
end;

function CompareVersion(str1, str2: String): Integer;
var
  temp1, temp2: String;
begin
    temp1 := str1;
    temp2 := str2;
    Result := CompareInner(temp1, temp2);
end;

function InitializeSetup(): Boolean;
var
  oldVersion: String;
  uninstaller: String;
  ErrorCode: Integer;
  vCurID      :String;
  vCurAppName :String;
begin
  vCurID:= '{#SetupSetting("AppId")}';
  vCurAppName:= '{#SetupSetting("AppName")}';
  //remove first "{" of ID
  vCurID:= Copy(vCurID, 2, Length(vCurID) - 1);
  //
  if RegKeyExists(HKEY_LOCAL_MACHINE,
    'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1') then
  begin
    RegQueryStringValue(HKEY_LOCAL_MACHINE,
      'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
      'DisplayVersion', oldVersion);
    if (CompareVersion(oldVersion, '{#SetupSetting("AppVersion")}') < 0) then      
    begin
      if MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. Continue to use this old version?',
        mbConfirmation, MB_YESNO) = IDYES then
      begin
        Result := False;
      end
      else
      begin
          RegQueryStringValue(HKEY_LOCAL_MACHINE,
            'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
            'UninstallString', uninstaller);
          ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
          Result := True;
      end;
    end
    else
    begin
      MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. This installer will exit.',
        mbInformation, MB_OK);
      Result := False;
    end;
  end
  else
  begin
    Result := True;
  end;
end;

-1

मेरा कुछ छूट रहा है। नई फ़ाइलें लक्ष्य निर्देशिका को कॉपी कर रहे हैं से पहले पुराने स्थापना को हटाने होता है। फिर आता है कि अनइंस्टालर उन्हें हटा देता है और निर्देशिका को हटा देता है।


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

मैं एक चालक को स्थापित करने के लिए INNO का उपयोग करता हूं और यह अनुप्रयोगों के साथ है। स्वाभाविक रूप से, वास्तविक चालक स्थापना / निष्कासन सीधे INNO द्वारा नहीं किया जाता है। बल्कि, INNO एक ड्राइवर इंस्टॉलर / रिमूवर ऐप को कॉपी करता है और फिर इसे चलाता है। समान रूप से अनइंस्टॉल करना: INNO चालक रिमूवर चलाता है, फिर फ़ाइलें हटाता है।
शाऊल

-8

[रन] अनुभाग का उपयोग न करें, लेकिन [स्थापना रद्द करें]। वास्तव में, [रन] के तहत प्रोग्राम को इंस्टॉलेशन के बाद निष्पादित किया जाता है, जिससे इंस्टॉलेशन के तुरंत बाद आपके प्रोग्राम को अनइंस्टॉल किया जा सकता है: - | इसके बजाय, स्थापना से पहले [स्थापना रद्द करें] अनुभाग का मूल्यांकन किया जाता है ।


3
[UninstallRun]सवाल का हल नहीं है।
क्रेग मैकक्वीन

-8

इस लिंक का पालन करें: http://news.jrsoftware.org/news/innosetup/msg55323.html

InitializeSetup () फ़ंक्शन में, आप उपयोगकर्ता के पुराने संस्करण की स्थापना रद्द करने के लिए उपयोगकर्ता संकेत के बाद "MSIEXEC / x {आपका प्रोग्राम ID}" कह सकते हैं


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