2009-10-22 18 views
17

मैंने एक प्रोग्राम लिखा है जो सर्वर पर एक नया संस्करण पाता है, लेकिन मुझे साफ-सफाई लागू करना मुश्किल लगता है।एक .NET प्रोग्राम खुद को कैसे अपडेट कर सकता है?

रिमोट सर्वर की जांच करना और फ़ाइल डाउनलोड करना काफी आसान है लेकिन फिर क्या? यह बस फ़ाइल नहीं कर सकता। कॉपी ("newversion.exe", "myprogram.exe") क्योंकि myprogram चल रहा है और फ़ाइल लॉक है।

मैं इसे दो फाइलों को नए संस्करण और अद्यतन डाउनलोड करके करता हूं। माइप्रोग्राम फिर अद्यतन और बाहर निकलता है। अद्यतन दो सेकंड के लिए इंतजार कर रहा है, प्रतिलिपि करता है, फिर myprogram (जो अब अद्यतन संस्करण है) लॉन्च करता है और बाहर निकलता है। माइप्रोग्राम अपडेट होने पर अपडेट करता है और इसे हटा देता है और इसे हटा देता है तो उसे नया कर देता है। माइप्रोग्राम अब नया संस्करण है जिसमें कोई भी फाइल शेष नहीं है।

इस से बेहतर तरीका होना चाहिए, इसलिए प्रोग्राम को अपडेट करने के लिए .NET तरीका क्या है?

पी एस। क्षमा करें अगर यह प्रश्न दो बार प्रकट होता है - मुझे पहली बार सबमिट किए जाने पर 'स्टैक ओवरफ़्लो टूटा हुआ' पृष्ठ मिला।

+0

क्या इनमें से कोई भी समाधान स्वीकार्य था? –

उत्तर

3

आप WIX या ClickOnce का उपयोग कर सकते हैं। वे इसे आपके लिए संभालते हैं।

+0

http://home.scarlet.be/~zippyv/zippydemo/ मेरी अद्यतन प्रस्तुति के लिए निर्बाध प्लग। – ZippyV

7

मैंने विक्स और क्लिकऑन दोनों को देखा और उन्हें प्यार नहीं किया। मैं कुछ आसान चाहता था, एक फ़ाइल "xcopy परिनियोजन" प्रकार WPF ऐप्स के लिए।

इसलिए मैंने एक बनाया। यह एक AppUpdater क्लास है जिसे आप किसी भी WPF ऐप में छोड़ सकते हैं, आवश्यक होने पर स्वचालित रूप से अपडेट हो जाता है।

संस्करण संख्या की जांच करना और नवीनतम संस्करण डाउनलोड करना आसान है।

अगला भाग कम आसान है। आप एक चल रहे ऐप को कैसे बदलते हैं?

  • हर बार यह चलता है, अनुप्रयोग एक संस्करण के लिए एक प्रसिद्ध यूआरएल की जाँच करता है: दृष्टिकोण मैं ले लिया इस था। यदि संस्करण वर्तमान में निष्पादित ऐप के संस्करण के बाद नहीं है, तो ऐसा करने के लिए और कुछ नहीं है।

  • यदि संस्करण बाद में है, तो ऐप एक नामित म्यूटेक्स पकड़ लेता है, एक अस्थायी स्थान पर स्वयं (विधानसभा.GetExecutingAssembly() स्थान) प्रतिलिपि बनाता है, फिर उस अस्थायी स्थान से एक नई प्रक्रिया (प्रक्रिया # 2) शुरू करता है, एक कमांड लाइन तर्क गुजर रहा है जो कहता है "आप अपडेट करने का प्रयास कर रहे हैं" और मूल exe स्थान दे रहे हैं।

  • प्रक्रिया # 1 खुद को बंद कर देता है।

  • प्रक्रिया # 2 शुरू होता है - यह देखता है कि यह अद्यतन करने का प्रयास कर रहा है, इसलिए यह अद्यतन छवि डाउनलोड करता है, और इसे मूल स्थान (कमांड लाइन पर स्थान दिया गया स्थान) में रखता है। 2 सेकंड, या किसी भी मनमाने ढंग से समय की प्रतीक्षा करने के बजाय, यह निर्धारित करने के लिए नामित Mutex का उपयोग करता है कि प्रक्रिया # 1 कब निकल गई है।

  • प्रक्रिया # 2 फिर मूल स्थान का उपयोग कर प्रक्रिया # 3 शुरू करता है।

  • प्रक्रिया # 2 बंद हो गई, जिसका नाम म्यूटेक्स जारी किया गया।

  • प्रक्रिया # 3 शुरू होती है। यह संस्करण यूआरएल की जांच करता है - यह देखता है कि यह चालू है।कोई अद्यतन आवश्यक नहीं है। प्रक्रिया # 3 भी अपने म्यूटेक्स को रिलीज़ करने के लिए प्रक्रिया # 2 की प्रतीक्षा करता है, और फिर EXE की अस्थायी प्रति को हटा देता है - जिसे प्रक्रिया # 2 द्वारा उपयोग किया गया था।


संपादित

टिप्पणी के जवाब में, हाँ, यह जटिल लग रहा है। लेकिन तर्क जो AppUpdater मॉड्यूल में है सब कुछ करता है। एक WPF app से इसका इस्तेमाल करने के लिए बहुत आसान है:

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
     // add this line in your constructor 
     if (UpdaterCheck()) this.Hide(); 
    } 

    // this is all boilerplate 
    private Ionic.AppUpdater.Wpf.Updater _updater; 
    private string _manifestUrl = "http://example.org/AppUpdates/MyApplication/Manifest.xml"; 
    private string _infoUrl  = "http://example.org/MyApplication.html"; 
    private string _description = "MyApplication is a delightful application; it does x, y, and z. "; 
    // Obtain the publicKey XML from the ManifestTool that ships with Ionic AppUpdater. 
    // The following string is Ionic's public key. You will need a different one. 
    // Consult the Readme for more information. 
    private string _publicKeyXml = "<RSAKeyValue><Modulus>sZqhvF0KX6m4blah..blah...=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; 

    // add this boilerplate method 
    private bool UpdaterCheck() 
    { 
     _updater = new Ionic.AppUpdater.Wpf.Updater("This is MyApplication.", 
                _infoUrl, 
                _description, 
                _manifestUrl, 
                _publicKeyXml); 
     return _updater.Status.IsUpdating; 
    } 
    ... 

Details and code you can run, here

यह केवल WPF क्षुधा के साथ काम करता है, लेकिन यह बहुत बात की एक WinForms संस्करण बनाने के लिए आसान होगा। वही विचार, हालांकि यूआई उत्पन्न करने वाले कुछ तर्कों को बदलना होगा।

+2

मुझे लगता है कि "सरल" से ClickOnce अब मान्य नहीं बार जब आप प्रतिक्रिया के अंत करने के लिए मिलता है (-: – Murph

+0

मैं अपनी बात देखते हैं, लेकिन पहले, उन सभी चरणों एप्लिकेशन के लिए अदृश्य है, और दूसरा, मैं नहीं था क्लिकऑन ब्राउज़र टाई-इन, या अन्य सभी हस्ताक्षर सामग्री आदि पर निर्भरता नहीं चाहते हैं। – Cheeso

2

इसका आसान आप "वैकल्पिक हल" पता है जब। आपका प्रोग्राम स्वयं को डाउनलोड नहीं कर सकता क्योंकि फ़ाइल चल रही प्रक्रिया से बंद है। कामकाज यह है कि फ़ाइल को पुनः नाम देना अभी भी संभव है। तो यहाँ तुम क्या करते है:

यदि आपके प्रोग्राम नाम हैं "myprogram.exe":

  1. myprogram.exe
  2. Myprogram.exe शुरू होता है खुद का एक नया संस्करण डाउनलोड लेकिन नाम के तहत "NewVersion .bak "
  3. चेक कि newversion.bak सही (md5 की जांच या कुछ और)
  4. myprogram.exe का नाम बदलता है डाउनलोड किया गया" myprogram.exe "से" myprogram.old "
  5. myprogram.exe का नाम बदलता है" NewVersion .bak "to" mypr ogram.exe "
  6. myprogram.exe ही पुन: प्रारंभ होता है, और देखा, इसके अपडेट किया गया।
  7. (वैकल्पिक) myprogram.exe "myprogram.old" को हटाए जाने पर मौजूद है।

यह आपको बाहरी अपडेटर के बिना आपके प्रोग्राम को अपडेट करने की अनुमति देगा।

+2

2b। myprogram.exe एक अपवाद फेंकता है क्योंकि इसमें प्रोग्राम फ़ाइलें फ़ोल्डर में व्यवस्थापक पहुंच नहीं है। – ZippyV

0

आप .NET's No Touch Deployment पर गौर कर सकते हैं। इसे कम-से-कम क्लिक करके, एक बार क्लिक करके प्रतिस्थापित किया गया था।

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

मैं कहता हूँ उस पर क्लिक करें-एक बार एक बेहतर समाधान है, लेकिन मैंने सोचा कि मैं उल्लेख करें कोई टच।

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