source: trunk/CrypUpdater/App.xaml.cs @ 2280

Last change on this file since 2280 was 2231, checked in by sauer, 11 years ago

AutoUpdate:

  • different handling of user permissions, needs to be tested separately on xp, vista and 7
File size: 10.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Configuration;
4using System.Data;
5using System.Diagnostics;
6using System.Linq;
7using System.Windows;
8using System.Collections;
9using System.Threading;
10using System.Windows.Threading;
11using System.IO;
12using Ionic.Zip;
13using System.ComponentModel;
14using System.Security.AccessControl;
15using System.Security.Principal;
16
17
18namespace CrypUpdater
19{
20    /// <summary>
21    /// Interaktionslogik für "App.xaml"
22    /// </summary>
23    public partial class App : Application
24    {
25
26        private MainWindow m;
27        private bool mayrestart = false;
28        internal static string CryptoolExePath;
29        private string ZipFilePath;
30        private string CryptoolFolderPath;
31        private int CryptoolProcessID;
32        private Process p;
33        private List<Process> unwantedProcesses = new List<Process>();
34
35
36        private void Application_Startup(object sender, StartupEventArgs e)
37        {
38
39            m = new CrypUpdater.MainWindow();
40
41            try
42            {
43                ZipFilePath = e.Args[0];
44                CryptoolFolderPath = e.Args[1];
45                CryptoolExePath = e.Args[2];
46                CryptoolProcessID = Convert.ToInt32(e.Args[3]);
47                mayrestart = Convert.ToBoolean(e.Args[4]);
48                p = Process.GetProcessById(CryptoolProcessID);
49
50                if (p.WaitForExit(1000 * 30))
51                {
52                    unwantedProcesses = FindCrypToolProcesses(CryptoolFolderPath);
53                    if (unwantedProcesses.Count == 0)
54                    {
55                        UnpackZip(ZipFilePath, CryptoolFolderPath);
56                    }
57                    else
58                    {
59                        AskForLicenseToKill();
60                    }
61
62                }
63                else
64                {
65                    MessageBoxButton b = MessageBoxButton.OKCancel;
66                    string caption = "Timeout error";
67                    MessageBoxResult result;
68                    result = MessageBox.Show("CrypTool 2.0 failed to shut down. Kill the process to proceed?", caption, b);
69                    if (result == MessageBoxResult.OK)
70                    {
71                        try
72                        {
73                            p.Kill();
74                            p.WaitForExit();
75                            unwantedProcesses = FindCrypToolProcesses(CryptoolFolderPath);
76                            if (unwantedProcesses.Count == 0)
77                            {
78                                UnpackZip(ZipFilePath, CryptoolFolderPath);
79                            }
80                            else
81                            {
82                                AskForLicenseToKill();
83                            }
84                        }
85                        catch (Exception)
86                        {
87                            unwantedProcesses = FindCrypToolProcesses(CryptoolFolderPath);
88                            if (unwantedProcesses.Count == 0)
89                            {
90                                UnpackZip(ZipFilePath, CryptoolFolderPath);
91                            }
92                            else
93                            {
94                                AskForLicenseToKill();
95                            }
96                        }
97                    }
98                    else
99                    {
100                        MessageBox.Show("Update failed. CrypTool 2.0 will be restarted.");
101                    }
102
103                }
104
105            }
106            catch (IndexOutOfRangeException) // parameter not set
107            {
108                if (CryptoolExePath != null)
109                {
110                    MessageBox.Show("Update failed. CrypTool 2.0 will be restarted.", "Error");
111                }
112                else
113                {
114                    UpdateFailure();
115                }
116            }
117            catch (FormatException) // no id or mayrestart was parsable
118            {
119                UpdateFailure();
120            }
121            catch (ArgumentException) // the invoking process has already exited (no such process with this id exists)
122            {
123                unwantedProcesses = FindCrypToolProcesses(CryptoolFolderPath);
124                if (unwantedProcesses.Count == 0)
125                {
126                    UnpackZip(ZipFilePath, CryptoolFolderPath);
127                }
128                else
129                {
130                    AskForLicenseToKill();
131                }
132            }
133
134            if(mayrestart)
135                RestartCryptool();
136            else
137                App.Current.Shutdown();
138
139        }
140
141        private void AskForLicenseToKill()
142        {
143            MessageBoxButton mbb = MessageBoxButton.YesNo;
144            string caption = "Error";
145            string messagePart1;
146            string messagePart2;
147            string messagePart3;
148            if (unwantedProcesses.Count > 1)
149            {
150                messagePart1 = "Several instances";
151                messagePart2 = "are";
152                messagePart3 = "these processes";
153            }
154            else
155            {
156                messagePart1 = "Another instance";
157                messagePart2 = "is";
158                messagePart3 = "this process";
159            }
160            MessageBoxResult result;
161            result = MessageBox.Show(messagePart1 + " of CrypTool 2.0 using the same resources " + messagePart2 + " still running. Kill " + messagePart3 + " to proceed?", caption, mbb);
162            if (result == MessageBoxResult.Yes)
163            {
164                KillOtherProcesses(unwantedProcesses);
165                UnpackZip(ZipFilePath, CryptoolFolderPath);
166            }
167            else
168            {
169                MessageBox.Show("Update failed. CrypTool 2.0 will be restarted.");
170            }
171        }
172
173        private static void KillOtherProcesses(List<Process> unwantedProcesses)
174        {
175            try
176            {
177                foreach (Process pr in unwantedProcesses)
178                {
179                    if (!pr.HasExited)
180                    {
181                        pr.Kill();
182                        pr.WaitForExit();
183                    }
184                }
185            }
186            catch (Exception)
187            {
188                MessageBox.Show("Update failed. Not able to remove remaining CrypTool 2.0 instances.", "Error");
189            }
190        }
191
192        private static void UpdateFailure()
193        {
194            MessageBox.Show("Update failed, wrong parameters!", "Error");
195            Application.Current.Shutdown();
196        }
197
198        private static void RestartCryptool()
199        {
200            try
201            {
202                System.Diagnostics.Process.Start(CryptoolExePath);
203                Application.Current.Shutdown();
204            }
205            catch (Exception)
206            {
207                MessageBoxButton bu = MessageBoxButton.OK;
208                string caption2 = "Error";
209                MessageBoxResult res = MessageBox.Show("CrypTool 2.0 could not be restarted! Try again later.", caption2, bu);
210                if (res == MessageBoxResult.OK)
211                {
212                    Application.Current.Shutdown();
213                }
214            }
215        }
216
217
218        private void UnpackZip(string ZipFilePath, string CryptoolFolderPath)
219        {
220
221            try
222            {
223                DirectorySecurity ds = Directory.GetAccessControl(CryptoolFolderPath);
224
225                using (ZipFile zip = ZipFile.Read(ZipFilePath))
226                {
227
228                    int count = zip.Entries.Count;
229                    int i = 0;
230                    int progress = 0;
231
232                    foreach (ZipEntry e in zip)
233                    {
234                        e.Extract(CryptoolFolderPath, ExtractExistingFileAction.OverwriteSilently);
235                        m.Show();
236                        i++;
237                        progress = i * 100 / count;
238                        m.UpdateProgress(progress);
239                    }
240
241                }
242
243            }
244            catch (UnauthorizedAccessException)
245            {
246
247                WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
248
249                if (!pricipal.IsInRole(WindowsBuiltInRole.Administrator))
250                {
251                    ProcessStartInfo psi = new ProcessStartInfo("CrypUpdater.exe", "\"" + ZipFilePath + "\" " + "\"" + CryptoolFolderPath + "\" " + "\"" + CryptoolExePath + "\" " + "\"" + CryptoolProcessID + "\" \"" + Boolean.FalseString + "\"");
252                    psi.UseShellExecute = true;
253                    psi.Verb = "runas";
254                    psi.WorkingDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
255                    Process cu = Process.Start(psi);
256                    cu.WaitForExit();
257                }
258                else
259                    MessageBox.Show("Extraction failed: CrypTool 2.0 will be restarted.", "Error");
260
261
262            }
263            catch (Exception e)
264            {
265                MessageBox.Show("Extraction failed: "+e.Message+". CrypTool 2.0 will be restarted.", "Error");
266            }
267
268        }
269
270
271        private List<Process> FindCrypToolProcesses(string cryptoolFolderPath)
272        {
273            List<Process> processList = new List<Process>();
274
275            try
276            {
277                Process[] p1 = Process.GetProcessesByName("CrypStartup");
278                foreach (Process p in p1)
279                {
280                    if (Path.GetDirectoryName(p.MainModule.FileName) == cryptoolFolderPath)
281                        processList.Add(p);
282                }
283            }
284            catch (Exception)
285            {
286                //32 bit updater cannot check for 64 bit processes
287            }
288
289            try
290            {
291                Process[] p2 = Process.GetProcessesByName("CrypWin");
292                foreach (Process p in p2)
293                {
294                    if (Path.GetDirectoryName(p.MainModule.FileName) == cryptoolFolderPath)
295                        processList.Add(p);
296                }
297            }
298            catch (Exception)
299            {
300                //32 bit updater cannot check for 64 bit processes
301            }
302
303            return processList;
304        }
305
306    }
307}
Note: See TracBrowser for help on using the repository browser.