프로젝트

일반

사용자정보

통계
| 개정판:

root / HAgent / Horizon(TCP, HTTP) / Horizon / UpdateClient.cs

이력 | 보기 | 이력해설 | 다운로드 (7.76 KB)

1 40 HKM
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Linq;
7
using System.Text;
8
using System.Threading.Tasks;
9
using System.Net;
10
using System.Xml;
11
using System.IO;
12
using System.Threading;
13
14
namespace Horizon
15
{
16
    public delegate void UpdateProgressCallback(int entireProgress, int partProgress);
17
18
    public class UpdateClient
19
    {
20
        public class NewFileInfo
21
        {
22
            public NewFileInfo(string path, DateTime lastWriteTime, long size)
23
            {
24
                this.path = path;
25
                this.lastWriteTime = lastWriteTime;
26
                this.size = size;
27
            }
28
            public override string ToString()
29
            {
30
                return path;
31
            }
32
            public long size;
33
            public string path;
34
            public DateTime lastWriteTime;
35
36
            public long oldLength = 0;
37
        }
38
39
        Queue<NewFileInfo> updateQueue = new Queue<NewFileInfo>();
40
        int needUpdateCount;
41
42
        UpdateProgressCallback progressCallback;
43
44
        XmlDocument updateXML = new XmlDocument();
45
        string defaultPath = @"Program\";
46
        string url;
47
        string project;
48
        public bool isUpdate;
49
50
        public UpdateClient()
51
        {
52
            if (!Directory.Exists("Program"))
53
            {
54
                Directory.CreateDirectory("Program");
55
            }
56
        }
57
        public enum RST_GetUpdateList { SUCCESS, FAIL_NETWORK, FAIL_XMLFORMAT }
58
        public RST_GetUpdateList GetUpdateList(string url, string project)
59
        {
60
            WebClient client = new WebClient();
61
            this.url = url;
62
            this.project = project;
63
            string xml;
64
            try
65
            {
66
               // xml = client.DownloadString(url + project + @"\UpdateLog.xml");
67
            }
68
            catch
69
            {
70
                return RST_GetUpdateList.FAIL_NETWORK;
71
            }
72
73
            try
74
            {
75
               // updateXML.LoadXml(xml);
76
            }
77
            catch
78
            {
79
                return RST_GetUpdateList.FAIL_XMLFORMAT;
80
            }
81
82
83
            XmlElement root = updateXML.DocumentElement;
84
85
            XmlNodeList files = root.ChildNodes;
86
87
            foreach (XmlNode file in files)
88
            {
89
                string path = file.FirstChild.InnerText;
90
                string length = file.ChildNodes[1].InnerText;
91
                string wt = file.ChildNodes[2].InnerText;
92
                if (IsNeedUpdate(path, DateTime.Parse(wt), length))
93
                {
94
                    updateQueue.Enqueue(new NewFileInfo(path, DateTime.Parse(wt), long.Parse(length)));
95
                }
96
            }
97
            needUpdateCount = updateQueue.Count;
98
            client.Dispose();
99
            return RST_GetUpdateList.SUCCESS;
100
        }
101
102
        private bool IsNeedUpdate(string path, DateTime writeTime, string length)
103
        {
104
            string localPath = defaultPath + path;
105
            FileInfo info;
106
            try
107
            {
108
                info = new FileInfo(localPath);
109
            }
110
            catch
111
            {
112
                return false;
113
            }
114
115
            if (info.Exists)
116
            {
117
                string size = info.Length.ToString();
118
                DateTime time = info.LastWriteTime;
119
120
                return !(time.Equals(writeTime) && size.Equals(length));
121
            }
122
            else
123
            {
124
                try
125
                {
126
                    string dirPath = localPath.Substring(0, localPath.LastIndexOf(@"\"));
127
                    Directory.CreateDirectory(dirPath);
128
                }
129
                catch
130
                {
131
                    return false;
132
                }
133
134
                return true;
135
            }
136
        }
137
138
139
        WebClient updateClient;
140
        public void StartUpdate(UpdateProgressCallback callback)
141
        {
142
            //Console.WriteLine(needUpdateCount);
143
            if (needUpdateCount == 0)
144
            {
145
                isUpdate = false;
146
                callback(100, 100);
147
                return;
148
            }
149
150
            isUpdate = true;
151
152
            progressCallback = callback;
153
154
            Update();
155
        }
156
        void Update()
157
        {
158
            if (updateQueue.Count == 0)
159
            {
160
                if (updateClient != null)
161
                    updateClient.Dispose();
162
                isUpdate = false;
163
                return;
164
            }
165
166
            DoDownloadFile(updateQueue.Dequeue());
167
        }
168
        private async void DoDownloadFile(NewFileInfo info)
169
        {
170
            bool isSuccess = false;
171
            long totalBytesRead = 0;
172
173
            using (FileStream localFileStream = new FileStream(defaultPath + info, FileMode.Create))
174
            {
175
                while (!isSuccess)
176
                {
177
                    try
178
                    {
179
                        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url + project + "/" + info);
180
                        httpRequest.Method = "GET";
181
                        httpRequest.AddRange(totalBytesRead, info.size);
182
183
                        // if the URI doesn't exist, exception gets thrown here...
184
                        using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
185
                        {
186
                            using (Stream responseStream = httpResponse.GetResponseStream())
187
                            {
188
                                var buffer = new byte[4096];
189
                                int bytesRead;
190
191
                                while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
192
                                {
193
                                    totalBytesRead += bytesRead;
194
                                    progressCallback((int)((1.0f - ((float)updateQueue.Count / needUpdateCount)) * 100), (int)((float)totalBytesRead / info.size * 100));
195
                                    await localFileStream.WriteAsync(buffer, 0, bytesRead);
196
                                }
197
                            }
198
                        }
199
                        localFileStream.Close();
200
                        FileInfo file = new FileInfo(defaultPath + info.path);
201
                        file.LastWriteTime = info.lastWriteTime;
202
                        isSuccess = true;
203
                    }
204
                    catch (Exception ex)
205
                    {
206
                        Thread.Sleep(100);
207
                    }
208
                }
209
            }
210
            Update();
211
212
        }
213
214
        public static string[] GetProjectList(string ftpAddress)
215
        {
216
            FtpWebRequest ftpRequest;
217
            try
218
            {
219
                ftpRequest = (FtpWebRequest)(WebRequest.Create(ftpAddress));
220
                ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
221
                ftpRequest.Credentials = new NetworkCredential("FTPUser", "1234");
222
                ftpRequest.UseBinary = true;
223
            }
224
            catch
225
            {
226
                return null;
227
            }
228
229
            try
230
            {
231
                FtpWebResponse respone = (FtpWebResponse)ftpRequest.GetResponse();
232
                StreamReader reader = new StreamReader(respone.GetResponseStream(), Encoding.Default);
233
                string data = reader.ReadToEnd();
234
                if (respone != null)
235
                {
236
                    respone.Close();
237
                }
238
                return data.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
239
            }
240
            catch
241
            {
242
                return null;
243
            }
244
245
        }
246
    }
247
}