Cでのプログラムの自動更新#

数年前、Delphiでプログラミングしている間に、私は個人的に特定の自動更新コードを作成しました。これは後に更新があるプログラムの開発に不可欠になりました。 現在、このコードはc#で完全に書き直されており、皆さんと共有したいと思います。



画像



まず、この実装の目標を定義します。


  1. 新しいバージョンが検出されると、更新が自動的に行われます。
  2. 更新後、プログラムは自動的に再起動します。
  3. 更新後、プログラム名は同じままにしてください。


問題は、プログラムが自分自身を削除、置換、再起動できないことです。 そして、この問題をどのように解決するのでしょうか? ここでは、すべてのコードを1つのファイルに保存するという目標を追求していないため、プログラムの名前変更と再起動を行う2番目のファイルが役立ちます。





ステージ



ステージ1:バージョンチェック


最適なオプションを探すのが面倒なので、2つのファイルがサイトに投稿されました。



はい、XML形式を使用します。 トピックを先読みして、version.xmlファイルにはファイルのいくつかのバージョンのリストがあると言いますが、1つだけを検討します。



どうぞ バージョンファイルの構造は次のとおりです。



<version> <myprogram>1.0.2.37</myprogram> </version>
      
      





backgroundWorkerコンポーネントは、DoWorkハンドラー内の次のコードでフォームに追加されます(バックグラウンドファイルのダウンロードを実装するため)。

 try { double versionRemote = Convert.ToDouble(doc.GetElementsByTagName("myprogram")[0].InnerText.Replace(".", "")), thisVersion = Convert.ToDouble(Application.ProductVersion.Replace(".", "")); if (thisVersion < versionRemote) { MessageBox.Show(this, "   (" + doc.GetElementsByTagName("myprogram")[0].InnerText + ")" + Environment.NewLine + "     .", Application.ProductName + " v" + Application.ProductVersion, MessageBoxButtons.OK, MessageBoxIcon.Information); var client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(download_ProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(download_Completed); client.DownloadFileAsync(new Uri(@"http://mysite/myprogram.exe"), "temp_myprogram"); } } catch (Exception) { }
      
      





上記のコードで見るもの:

バージョンには多数の値を設定できるため、double変数タイプを使用します。 バージョンを比較するために、すべてのポイントを削除し、バージョンを文字列から数値に変換します(例では、数値10237を取得します)。

thisVersion変数に割り当てられたファイル自体のバージョンでも同じことを行います。



その後、ローカルバージョンをリモートバージョンと比較する必要があります。バージョンがリモートバージョンよりも小さい場合は、最初にさらなる更新を通知するメッセージを表示します。 その後、プログラムは起動された場所と同じフォルダにファイルのダウンロードを開始します。 ファイルの名前はtemp_myprogramです。



ダウンロードのステータスを監視するために、progressBarコンポーネントがフォームに追加され、関数がコードに追加されました。



 private void download_ProgressChanged(object sender, DownloadProgressChangedEventArgs e) { try { progressBar1.Value = e.ProgressPercentage; } catch (Exception) { } }
      
      





この関数は、進行状況バーにファイルのダウンロードステータスを表示します。 これは視覚表示専用です。

それで、私たちはファイルをアップロードし、次に何をすべきか? そして、次のコードを含むdownload_Completed関数が実行されます。



 private void download_Completed(object sender, AsyncCompletedEventArgs e) { try { Process.Start("updater.exe", "temp_myprogram myprogram.exe"); Process.GetCurrentProcess().Kill(); } catch (Exception) { } }
      
      





ここではすべてが簡単です。次のステップで説明するパラメーターを使用してupdater.exeファイルを実行します。

2行目は、アプリケーションを強制的にシャットダウンする必要があることを示しています。



ステージ2:更新処理


次に、 updater.exeユーティリティが役立ちます。この機能の機能は、メインアプリケーションのシャットダウンの確認と更新の処理です。

さて、テキストに入らず、コードにまっすぐ進みましょう。



 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Threading; namespace Updater { class Program { static void Main(string[] args) { try { string process = args[1].Replace(".exe", ""); Console.WriteLine("Terminate process!"); while (Process.GetProcessesByName(process).Length > 0) { Process[] myProcesses2 = Process.GetProcessesByName(process); for (int i = 1; i < myProcesses2.Length; i++) { myProcesses2[i].Kill(); } Thread.Sleep(300); } if(File.Exits(args[1])){ File.Delete(args[1]); } File.Move(args[1], args[0]); Console.WriteLine("Starting "+args[1]); Process.Start(args[1]); } catch (Exception) { } } } }
      
      





フォームは必要ないため、プロジェクトは通常のコンソールアプリケーションとして構築され、そのアクションは非常に簡単です。

2番目のパラメーターで指定されたプロセスが実行されているかどうかをチェックするループを設定します。 プロセスが見つかった場合、強制終了のためにKill()コマンドが送信され、その後300ミリ秒待機して繰り返します。 プロセスが完了するまでループが実行されます。



次に、古いファイルを削除します。 いくつかのエラー(脳内のエラー)を排除するために、ファイルの存在をチェックする機能を追加します。

削除後、1番目のパラメーターで指定されたファイルの名前を2番目のパラメーターで指定された名前に変更します。 この場合、 temp_myprogramファイルの名前はmyprogram.exeに変更され、その後myprogram.exeプロセスが起動され、このアップデーターのウィンドウが閉じられます。

また、特定のアプリケーションへのバインディングがないため、必要なすべてのプロジェクトでアップデータープログラムファイルを使用します。



そして次のステップに進みます。



ステージ3:完了




これで、更新されたバージョンファイルが正常に起動し、「アップデータ」ウィンドウが閉じたことがわかります。 利益!



この記事は、World of Tanksゲーム用のPRO Tanks modpackのランチャーに基づいて作成され、アプリケーションのオリジナルのスクリーンショットが含まれています。 「この機能はありません」と言う人のために、このランチャーはベータテスト中であり、限られた人数が利用できるとすぐに言います。



誰かがupdater.exeファイルを必要とするなら、あなたはいつでも私の公式サイトから現在のバージョンをダウンロードできます。 現在、現在のバージョンは1.0.0.2です。



そして、この行で、自動更新コードは終了します。



UPD。 私は、修正の一部を含む2番目の記事を書きました。

「不正な手」、「不正なコード」などについてまだ考えている人には、少なくとも何が間違っているかをコメントで書いてください。 あなたの建設的な批判に基づいて、私は私の仕事を改善し、それによってより良いコードを書く方法を学びます。

事前に感謝します!



よろしく、アンドリュー・ヘルダー!



All Articles