개정판 c4a4d59c
issue #660 SmartUpdate 구현
KCOM/App.xaml.cs | ||
---|---|---|
1 | 1 |
|
2 |
using KCOM.ServiceDeepView; |
|
2 | 3 |
using System; |
3 | 4 |
using System.Collections.Generic; |
4 | 5 |
using System.ComponentModel; |
5 | 6 |
using System.Configuration; |
6 | 7 |
using System.Data; |
8 |
using System.Diagnostics; |
|
9 |
using System.IO; |
|
7 | 10 |
using System.Linq; |
11 |
using System.Net; |
|
12 |
using System.Reflection; |
|
8 | 13 |
using System.Runtime.CompilerServices; |
9 | 14 |
using System.ServiceModel; |
10 | 15 |
using System.Windows; |
16 |
using System.Xml; |
|
11 | 17 |
|
12 | 18 |
namespace KCOM |
13 | 19 |
{ |
... | ... | |
56 | 62 |
return Newtonsoft.Json.JsonConvert.DeserializeObject<OpenProperties>(jsonBack); |
57 | 63 |
} |
58 | 64 |
|
65 |
//20180921 LJY |
|
66 |
//public ServiceDeepViewClient _Client; |
|
67 |
|
|
68 |
|
|
69 |
private string versionPath = null; |
|
70 |
|
|
59 | 71 |
protected override void OnStartup(StartupEventArgs e) |
60 | 72 |
{ |
61 | 73 |
try |
62 | 74 |
{ |
63 | 75 |
if (e.Args.Count() > 0) |
64 | 76 |
{ |
65 |
|
|
66 |
var result = ParamDecoding(e.Args[0].Replace(@"kcom://","").Replace(@"/","")); |
|
77 |
var result = ParamDecoding(e.Args[0].Replace(@"kcom://", "").Replace(@"/", "")); |
|
67 | 78 |
App.ViewInfo = new IKCOM.ViewInfo |
68 | 79 |
{ |
69 | 80 |
DocumentItemID = result.DocumentItemID, |
... | ... | |
78 | 89 |
}; |
79 | 90 |
ParameterMode = true; |
80 | 91 |
} |
92 |
else |
|
93 |
{ |
|
94 |
string[] strArg = Environment.GetCommandLineArgs(); |
|
95 |
if (strArg.Length > 1) |
|
96 |
{ |
|
97 |
//label1.Text = strArg[1]; |
|
98 |
|
|
99 |
var result = ParamDecoding(strArg[1].Replace(@"kcom://", "").Replace(@"/", "")); |
|
100 |
App.ViewInfo = new IKCOM.ViewInfo |
|
101 |
{ |
|
102 |
DocumentItemID = result.DocumentItemID, |
|
103 |
//DocumentItemID = "10001", |
|
104 |
bPartner = result.bPartner, |
|
105 |
CreateFinalPDFPermission = result.CreateFinalPDFPermission, |
|
106 |
NewCommentPermission = result.NewCommentPermission, |
|
107 |
ProjectNO = result.ProjectNO, |
|
108 |
UserID = result.UserID, |
|
109 |
//UserID = "H2009115", |
|
110 |
//Mode = 0 , 1 , 2 |
|
111 |
}; |
|
112 |
ParameterMode = true; |
|
113 |
} |
|
114 |
} |
|
81 | 115 |
|
82 | 116 |
//App.ViewInfo.CreateFinalPDFPermission = false; |
83 | 117 |
//App.ViewInfo.NewCommentPermission = false; |
84 | 118 |
|
85 |
//GetQueryStringParameters(); |
|
86 |
_binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly); |
|
119 |
//GetQueryStringParameters();
|
|
120 |
_binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
|
|
87 | 121 |
_binding.MaxBufferSize = 2147483647; |
88 | 122 |
_binding.MaxReceivedMessageSize = 2147483647; |
89 | 123 |
_binding.OpenTimeout = new TimeSpan(0, 1, 0); |
... | ... | |
102 | 136 |
#else |
103 | 137 |
_EndPoint = new EndpointAddress(string.Format("{0}/ServiceDeepView.svc", sBaseServiceURL)); |
104 | 138 |
#endif |
105 |
base.OnStartup(e); |
|
139 |
|
|
140 |
//20180913 LJY 어셈블리 버전 |
|
141 |
//string assemblyVersion = Assembly.LoadFile('your assembly file').GetName().Version.ToString(); |
|
142 |
//string fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; |
|
143 |
//string productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion; |
|
144 |
//_Client = new ServiceDeepViewClient(App._binding, App._EndPoint); |
|
145 |
//var serverVersion = _Client.GetCurrentVersion(); |
|
146 |
|
|
147 |
if (Environment.Is64BitProcess == true) //64 bit machine |
|
148 |
{ |
|
149 |
versionPath = KCOM.Properties.Settings.Default.UpdateVer64; |
|
150 |
} |
|
151 |
else //32 bit machine |
|
152 |
{ |
|
153 |
versionPath = KCOM.Properties.Settings.Default.UpdateVer86; |
|
154 |
} |
|
155 |
|
|
156 |
// 20180921 version.xml check로 변경 |
|
157 |
var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); |
|
158 |
try |
|
159 |
{ |
|
160 |
XmlDocument xdoc = new XmlDocument(); |
|
161 |
xdoc.Load(versionPath); |
|
162 |
XmlNode node = xdoc.SelectSingleNode("/RootElement/version"); |
|
163 |
|
|
164 |
if (assemblyVersion != node.InnerText) // node.InnerText 가 null이면 catch로 빠짐 |
|
165 |
{ |
|
166 |
if(MessageBox.Show("Ver. " + node.InnerText + " 업데이트가 있습니다.\r\nSmartUpdate를 실행합니다.", "MARKUS", MessageBoxButton.OKCancel) == MessageBoxResult.OK) |
|
167 |
{ |
|
168 |
UpdateCheck(e); |
|
169 |
} |
|
170 |
else |
|
171 |
{ |
|
172 |
base.Shutdown(); |
|
173 |
//현재 실행되고 있는 자기 자신 프로세스의 정보 // 위에꺼랑 두개 다 써줄필요가 있는..가? |
|
174 |
Process proc = Process.GetCurrentProcess(); |
|
175 |
proc.Kill(); |
|
176 |
} |
|
177 |
} |
|
178 |
else |
|
179 |
{ |
|
180 |
base.OnStartup(e); |
|
181 |
} |
|
182 |
} |
|
183 |
catch (Exception ex) //2. 파일이 없거나 파일내에 version의 값이 없다면 KCOM 실행하기 |
|
184 |
{ |
|
185 |
ErrorLogFileWrite("KCOM//UpdateCheck ERR : " + ex); |
|
186 |
base.OnStartup(e); |
|
187 |
} |
|
106 | 188 |
} |
107 | 189 |
catch (Exception ex) |
108 | 190 |
{ |
109 | 191 |
MessageBox.Show("에러 메시지" + ex.Message); |
110 | 192 |
} |
111 | 193 |
} |
194 |
|
|
195 |
protected void UpdateCheck(StartupEventArgs e) |
|
196 |
{ |
|
197 |
try |
|
198 |
{ |
|
199 |
if (e.Args.Count() > 0) |
|
200 |
{ |
|
201 |
ProcessStartInfo proInfo = new ProcessStartInfo(); |
|
202 |
var FileName = AppDomain.CurrentDomain.BaseDirectory + "SmartUpdate.exe"; |
|
203 |
|
|
204 |
Process.Start(FileName, e.Args[0]); |
|
205 |
|
|
206 |
//다른프로그램에서는 값 안넘기고 바로 실행해도 오류 없이 파일 업데이트 잘 됨! |
|
207 |
//Process.Start(FileName); |
|
208 |
|
|
209 |
base.Shutdown(); |
|
210 |
//현재 실행되고 있는 자기 자신 프로세스의 정보 |
|
211 |
Process proc = Process.GetCurrentProcess(); |
|
212 |
proc.Kill(); |
|
213 |
} |
|
214 |
} |
|
215 |
catch(Exception ee) |
|
216 |
{ |
|
217 |
ErrorLogFileWrite("KCOM//UpdateCheck ERR : " + ee); |
|
218 |
} |
|
219 |
} |
|
220 |
|
|
221 |
private void ErrorLogFileWrite(string Err) |
|
222 |
{ |
|
223 |
try |
|
224 |
{ |
|
225 |
string pathString = AppDomain.CurrentDomain.BaseDirectory + "Err"; |
|
226 |
if (!File.Exists(pathString)) |
|
227 |
{ |
|
228 |
Directory.CreateDirectory(pathString); |
|
229 |
} |
|
230 |
|
|
231 |
Err = Err + " " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "\r\n"; |
|
232 |
string path = pathString + "\\" + "Log_" + DateTime.Now.ToString("yyyy-MM-dd hh-mm") + ".txt"; |
|
233 |
File.AppendAllText(path, Err); |
|
234 |
} |
|
235 |
catch (Exception er) |
|
236 |
{ |
|
237 |
string strError = er.ToString(); |
|
238 |
//MessageBox.Show("err : " + er); |
|
239 |
} |
|
240 |
} |
|
112 | 241 |
} |
113 | 242 |
} |
KCOM/Properties/Settings.Designer.cs | ||
---|---|---|
12 | 12 |
|
13 | 13 |
|
14 | 14 |
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
15 |
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.6.0.0")]
|
|
15 |
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
|
|
16 | 16 |
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { |
17 | 17 |
|
18 | 18 |
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
... | ... | |
102 | 102 |
this["HubAddress"] = value; |
103 | 103 |
} |
104 | 104 |
} |
105 |
|
|
106 |
[global::System.Configuration.ApplicationScopedSettingAttribute()] |
|
107 |
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
|
108 |
[global::System.Configuration.DefaultSettingValueAttribute("http://www.devdoftech.co.kr:5977/TileSource/Version/version_x64.xml")] |
|
109 |
public string UpdateVer64 |
|
110 |
{ |
|
111 |
get |
|
112 |
{ |
|
113 |
return ((string)(this["UpdateVer64"])); |
|
114 |
} |
|
115 |
} |
|
116 |
|
|
117 |
[global::System.Configuration.ApplicationScopedSettingAttribute()] |
|
118 |
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
|
119 |
[global::System.Configuration.DefaultSettingValueAttribute("http://www.devdoftech.co.kr:5977/TileSource/Version/version_x86.xml")] |
|
120 |
public string UpdateVer86 |
|
121 |
{ |
|
122 |
get |
|
123 |
{ |
|
124 |
return ((string)(this["UpdateVer86"])); |
|
125 |
} |
|
126 |
} |
|
105 | 127 |
} |
106 | 128 |
} |
KCOM/Properties/Settings.settings | ||
---|---|---|
26 | 26 |
<Setting Name="HubAddress" Type="System.String" Scope="User"> |
27 | 27 |
<Value Profile="(Default)">http://www.devdoftech.co.kr:5100/</Value> |
28 | 28 |
</Setting> |
29 |
<Setting Name="UpdateVer64" Type="System.String" Scope="Application"> |
|
30 |
<Value Profile="(Default)">http://www.devdoftech.co.kr:5977/TileSource/Version/version_x64.xml</Value> |
|
31 |
</Setting> |
|
32 |
<Setting Name="UpdateVer86" Type="System.String" Scope="Application"> |
|
33 |
<Value Profile="(Default)">http://www.devdoftech.co.kr:5977/TileSource/Version/version_x86.xml</Value> |
|
34 |
</Setting> |
|
29 | 35 |
</Settings> |
30 | 36 |
</SettingsFile> |
SmartUpdate/App.xaml | ||
---|---|---|
1 |
<Application x:Class="SmartUpdate.App" |
|
2 |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
3 |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
4 |
xmlns:local="clr-namespace:SmartUpdate" |
|
5 |
StartupUri="MainWindow.xaml"> |
|
6 |
<Application.Resources> |
|
7 |
|
|
8 |
</Application.Resources> |
|
9 |
</Application> |
SmartUpdate/App.xaml.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Configuration; |
|
4 |
using System.Data; |
|
5 |
using System.Linq; |
|
6 |
using System.Threading.Tasks; |
|
7 |
using System.Windows; |
|
8 |
|
|
9 |
namespace SmartUpdate |
|
10 |
{ |
|
11 |
/// <summary> |
|
12 |
/// App.xaml에 대한 상호 작용 논리 |
|
13 |
/// </summary> |
|
14 |
public partial class App : Application |
|
15 |
{ |
|
16 |
} |
|
17 |
} |
SmartUpdate/FileToImageIconConverter.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Linq; |
|
4 |
using System.Text; |
|
5 |
|
|
6 |
namespace SmartUpdate |
|
7 |
{ |
|
8 |
#region FileToImageIconConverter |
|
9 |
public class FileToImageIconConverter |
|
10 |
{ |
|
11 |
private string filePath; |
|
12 |
private System.Windows.Media.ImageSource icon; |
|
13 |
|
|
14 |
public string FilePath { get { return filePath; } } |
|
15 |
|
|
16 |
public System.Windows.Media.ImageSource Icon |
|
17 |
{ |
|
18 |
get |
|
19 |
{ |
|
20 |
if (icon == null && System.IO.File.Exists(FilePath)) |
|
21 |
{ |
|
22 |
using (System.Drawing.Icon sysicon = System.Drawing.Icon.ExtractAssociatedIcon(FilePath)) |
|
23 |
{ |
|
24 |
icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon( |
|
25 |
sysicon.Handle, |
|
26 |
System.Windows.Int32Rect.Empty, |
|
27 |
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); |
|
28 |
} |
|
29 |
} |
|
30 |
|
|
31 |
return icon; |
|
32 |
} |
|
33 |
} |
|
34 |
|
|
35 |
public FileToImageIconConverter(string filePath) |
|
36 |
{ |
|
37 |
this.filePath = filePath; |
|
38 |
} |
|
39 |
} |
|
40 |
#endregion |
|
41 |
} |
SmartUpdate/IconHelper.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Drawing; |
|
3 |
using System.Collections; |
|
4 |
using System.ComponentModel; |
|
5 |
using System.Data; |
|
6 |
using System.Runtime.InteropServices; |
|
7 |
|
|
8 |
namespace Etier.IconHelper |
|
9 |
{ |
|
10 |
/// <summary> |
|
11 |
/// Provides static methods to read system icons for both folders and files. |
|
12 |
/// </summary> |
|
13 |
/// <example> |
|
14 |
/// <code>IconReader.GetFileIcon("c:\\general.xls");</code> |
|
15 |
/// </example> |
|
16 |
public class IconReader |
|
17 |
{ |
|
18 |
/// <summary> |
|
19 |
/// Options to specify the size of icons to return. |
|
20 |
/// </summary> |
|
21 |
public enum IconSize |
|
22 |
{ |
|
23 |
/// <summary> |
|
24 |
/// Specify large icon - 32 pixels by 32 pixels. |
|
25 |
/// </summary> |
|
26 |
Large = 0, |
|
27 |
/// <summary> |
|
28 |
/// Specify small icon - 16 pixels by 16 pixels. |
|
29 |
/// </summary> |
|
30 |
Small = 1 |
|
31 |
} |
|
32 |
|
|
33 |
/// <summary> |
|
34 |
/// Options to specify whether folders should be in the open or closed state. |
|
35 |
/// </summary> |
|
36 |
public enum FolderType |
|
37 |
{ |
|
38 |
/// <summary> |
|
39 |
/// Specify open folder. |
|
40 |
/// </summary> |
|
41 |
Open = 0, |
|
42 |
/// <summary> |
|
43 |
/// Specify closed folder. |
|
44 |
/// </summary> |
|
45 |
Closed = 1 |
|
46 |
} |
|
47 |
|
|
48 |
/// <summary> |
|
49 |
/// Returns an icon for a given file - indicated by the name parameter. |
|
50 |
/// </summary> |
|
51 |
/// <param name="name">Pathname for file.</param> |
|
52 |
/// <param name="size">Large or small</param> |
|
53 |
/// <param name="linkOverlay">Whether to include the link icon</param> |
|
54 |
/// <returns>System.Drawing.Icon</returns> |
|
55 |
public static System.Drawing.Icon GetFileIcon(string name, IconSize size, bool linkOverlay) |
|
56 |
{ |
|
57 |
Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); |
|
58 |
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; |
|
59 |
|
|
60 |
if (true == linkOverlay) flags += Shell32.SHGFI_LINKOVERLAY; |
|
61 |
|
|
62 |
/* Check the size specified for return. */ |
|
63 |
if (IconSize.Small == size) |
|
64 |
{ |
|
65 |
flags += Shell32.SHGFI_SMALLICON; |
|
66 |
} |
|
67 |
else |
|
68 |
{ |
|
69 |
flags += Shell32.SHGFI_LARGEICON; |
|
70 |
} |
|
71 |
|
|
72 |
Shell32.SHGetFileInfo(name, |
|
73 |
Shell32.FILE_ATTRIBUTE_NORMAL, |
|
74 |
ref shfi, |
|
75 |
(uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi), |
|
76 |
flags); |
|
77 |
|
|
78 |
// Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly |
|
79 |
System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); |
|
80 |
User32.DestroyIcon(shfi.hIcon); // Cleanup |
|
81 |
return icon; |
|
82 |
} |
|
83 |
|
|
84 |
/// <summary> |
|
85 |
/// Used to access system folder icons. |
|
86 |
/// </summary> |
|
87 |
/// <param name="size">Specify large or small icons.</param> |
|
88 |
/// <param name="folderType">Specify open or closed FolderType.</param> |
|
89 |
/// <returns>System.Drawing.Icon</returns> |
|
90 |
public static System.Drawing.Icon GetFolderIcon(IconSize size, FolderType folderType) |
|
91 |
{ |
|
92 |
// Need to add size check, although errors generated at present! |
|
93 |
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; |
|
94 |
|
|
95 |
if (FolderType.Open == folderType) |
|
96 |
{ |
|
97 |
flags += Shell32.SHGFI_OPENICON; |
|
98 |
} |
|
99 |
|
|
100 |
if (IconSize.Small == size) |
|
101 |
{ |
|
102 |
flags += Shell32.SHGFI_SMALLICON; |
|
103 |
} |
|
104 |
else |
|
105 |
{ |
|
106 |
flags += Shell32.SHGFI_LARGEICON; |
|
107 |
} |
|
108 |
|
|
109 |
// Get the folder icon |
|
110 |
Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); |
|
111 |
Shell32.SHGetFileInfo(null, |
|
112 |
Shell32.FILE_ATTRIBUTE_DIRECTORY, |
|
113 |
ref shfi, |
|
114 |
(uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi), |
|
115 |
flags); |
|
116 |
|
|
117 |
System.Drawing.Icon.FromHandle(shfi.hIcon); // Load the icon from an HICON handle |
|
118 |
|
|
119 |
// Now clone the icon, so that it can be successfully stored in an ImageList |
|
120 |
System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); |
|
121 |
|
|
122 |
User32.DestroyIcon(shfi.hIcon); // Cleanup |
|
123 |
return icon; |
|
124 |
} |
|
125 |
} |
|
126 |
|
|
127 |
/// <summary> |
|
128 |
/// Wraps necessary Shell32.dll structures and functions required to retrieve Icon Handles using SHGetFileInfo. Code |
|
129 |
/// courtesy of MSDN Cold Rooster Consulting case study. |
|
130 |
/// </summary> |
|
131 |
/// |
|
132 |
|
|
133 |
// This code has been left largely untouched from that in the CRC example. The main changes have been moving |
|
134 |
// the icon reading code over to the IconReader type. |
|
135 |
public class Shell32 |
|
136 |
{ |
|
137 |
|
|
138 |
public const int MAX_PATH = 256; |
|
139 |
[StructLayout(LayoutKind.Sequential)] |
|
140 |
public struct SHITEMID |
|
141 |
{ |
|
142 |
public ushort cb; |
|
143 |
[MarshalAs(UnmanagedType.LPArray)] |
|
144 |
public byte[] abID; |
|
145 |
} |
|
146 |
|
|
147 |
[StructLayout(LayoutKind.Sequential)] |
|
148 |
public struct ITEMIDLIST |
|
149 |
{ |
|
150 |
public SHITEMID mkid; |
|
151 |
} |
|
152 |
|
|
153 |
[StructLayout(LayoutKind.Sequential)] |
|
154 |
public struct BROWSEINFO |
|
155 |
{ |
|
156 |
public IntPtr hwndOwner; |
|
157 |
public IntPtr pidlRoot; |
|
158 |
public IntPtr pszDisplayName; |
|
159 |
[MarshalAs(UnmanagedType.LPTStr)] |
|
160 |
public string lpszTitle; |
|
161 |
public uint ulFlags; |
|
162 |
public IntPtr lpfn; |
|
163 |
public int lParam; |
|
164 |
public IntPtr iImage; |
|
165 |
} |
|
166 |
|
|
167 |
// Browsing for directory. |
|
168 |
public const uint BIF_RETURNONLYFSDIRS = 0x0001; |
|
169 |
public const uint BIF_DONTGOBELOWDOMAIN = 0x0002; |
|
170 |
public const uint BIF_STATUSTEXT = 0x0004; |
|
171 |
public const uint BIF_RETURNFSANCESTORS = 0x0008; |
|
172 |
public const uint BIF_EDITBOX = 0x0010; |
|
173 |
public const uint BIF_VALIDATE = 0x0020; |
|
174 |
public const uint BIF_NEWDIALOGSTYLE = 0x0040; |
|
175 |
public const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX); |
|
176 |
public const uint BIF_BROWSEINCLUDEURLS = 0x0080; |
|
177 |
public const uint BIF_BROWSEFORCOMPUTER = 0x1000; |
|
178 |
public const uint BIF_BROWSEFORPRINTER = 0x2000; |
|
179 |
public const uint BIF_BROWSEINCLUDEFILES = 0x4000; |
|
180 |
public const uint BIF_SHAREABLE = 0x8000; |
|
181 |
|
|
182 |
[StructLayout(LayoutKind.Sequential)] |
|
183 |
public struct SHFILEINFO |
|
184 |
{ |
|
185 |
public const int NAMESIZE = 80; |
|
186 |
public IntPtr hIcon; |
|
187 |
public int iIcon; |
|
188 |
public uint dwAttributes; |
|
189 |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] |
|
190 |
public string szDisplayName; |
|
191 |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)] |
|
192 |
public string szTypeName; |
|
193 |
}; |
|
194 |
|
|
195 |
public const uint SHGFI_ICON = 0x000000100; // get icon |
|
196 |
public const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name |
|
197 |
public const uint SHGFI_TYPENAME = 0x000000400; // get type name |
|
198 |
public const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes |
|
199 |
public const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location |
|
200 |
public const uint SHGFI_EXETYPE = 0x000002000; // return exe type |
|
201 |
public const uint SHGFI_SYSICONINDEX = 0x000004000; // get system icon index |
|
202 |
public const uint SHGFI_LINKOVERLAY = 0x000008000; // put a link overlay on icon |
|
203 |
public const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state |
|
204 |
public const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes |
|
205 |
public const uint SHGFI_LARGEICON = 0x000000000; // get large icon |
|
206 |
public const uint SHGFI_SMALLICON = 0x000000001; // get small icon |
|
207 |
public const uint SHGFI_OPENICON = 0x000000002; // get open icon |
|
208 |
public const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon |
|
209 |
public const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl |
|
210 |
public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute |
|
211 |
public const uint SHGFI_ADDOVERLAYS = 0x000000020; // apply the appropriate overlays |
|
212 |
public const uint SHGFI_OVERLAYINDEX = 0x000000040; // Get the index of the overlay |
|
213 |
|
|
214 |
public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; |
|
215 |
public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; |
|
216 |
|
|
217 |
[DllImport("Shell32.dll")] |
|
218 |
public static extern IntPtr SHGetFileInfo( |
|
219 |
string pszPath, |
|
220 |
uint dwFileAttributes, |
|
221 |
ref SHFILEINFO psfi, |
|
222 |
uint cbFileInfo, |
|
223 |
uint uFlags |
|
224 |
); |
|
225 |
} |
|
226 |
|
|
227 |
/// <summary> |
|
228 |
/// Wraps necessary functions imported from User32.dll. Code courtesy of MSDN Cold Rooster Consulting example. |
|
229 |
/// </summary> |
|
230 |
public class User32 |
|
231 |
{ |
|
232 |
/// <summary> |
|
233 |
/// Provides access to function required to delete handle. This method is used internally |
|
234 |
/// and is not required to be called separately. |
|
235 |
/// </summary> |
|
236 |
/// <param name="hIcon">Pointer to icon handle.</param> |
|
237 |
/// <returns>N/A</returns> |
|
238 |
[DllImport("User32.dll")] |
|
239 |
public static extern int DestroyIcon(IntPtr hIcon); |
|
240 |
} |
|
241 |
} |
|
242 |
|
SmartUpdate/IconManager.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Linq; |
|
4 |
using System.Text; |
|
5 |
using System.Drawing; |
|
6 |
using System.Runtime.InteropServices; |
|
7 |
using System.Windows.Media; |
|
8 |
using System.Windows; |
|
9 |
using System.Windows.Media.Imaging; |
|
10 |
|
|
11 |
public class IconManager |
|
12 |
{ |
|
13 |
public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory) |
|
14 |
{ |
|
15 |
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES; |
|
16 |
if (smallIcon) |
|
17 |
flags |= SHGFI_SMALLICON; |
|
18 |
|
|
19 |
uint attributes = FILE_ATTRIBUTE_NORMAL; |
|
20 |
if (isDirectory) |
|
21 |
attributes |= FILE_ATTRIBUTE_DIRECTORY; |
|
22 |
|
|
23 |
SHFILEINFO shfi; |
|
24 |
if (0 != SHGetFileInfo(path, attributes, out shfi, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags)) |
|
25 |
{ |
|
26 |
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); |
|
27 |
} |
|
28 |
return null; |
|
29 |
} |
|
30 |
|
|
31 |
[StructLayout(LayoutKind.Sequential)] |
|
32 |
private struct SHFILEINFO |
|
33 |
{ |
|
34 |
public IntPtr hIcon; |
|
35 |
public int iIcon; |
|
36 |
public uint dwAttributes; |
|
37 |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] |
|
38 |
public string szDisplayName; |
|
39 |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] |
|
40 |
public string szTypeName; |
|
41 |
} |
|
42 |
|
|
43 |
[DllImport("shell32")] |
|
44 |
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags); |
|
45 |
|
|
46 |
private const uint FILE_ATTRIBUTE_READONLY = 0x00000001; |
|
47 |
private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002; |
|
48 |
private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004; |
|
49 |
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; |
|
50 |
private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020; |
|
51 |
private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040; |
|
52 |
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; |
|
53 |
private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100; |
|
54 |
private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200; |
|
55 |
private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400; |
|
56 |
private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800; |
|
57 |
private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000; |
|
58 |
private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000; |
|
59 |
private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000; |
|
60 |
private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000; |
|
61 |
|
|
62 |
private const uint SHGFI_ICON = 0x000000100; |
|
63 |
private const uint SHGFI_DISPLAYNAME = 0x000000200; |
|
64 |
private const uint SHGFI_TYPENAME = 0x000000400; |
|
65 |
private const uint SHGFI_ATTRIBUTES = 0x000000800; |
|
66 |
private const uint SHGFI_ICONLOCATION = 0x000001000; |
|
67 |
private const uint SHGFI_EXETYPE = 0x000002000; |
|
68 |
private const uint SHGFI_SYSICONINDEX = 0x000004000; |
|
69 |
private const uint SHGFI_LINKOVERLAY = 0x000008000; |
|
70 |
private const uint SHGFI_SELECTED = 0x000010000; |
|
71 |
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000; |
|
72 |
private const uint SHGFI_LARGEICON = 0x000000000; |
|
73 |
private const uint SHGFI_SMALLICON = 0x000000001; |
|
74 |
private const uint SHGFI_OPENICON = 0x000000002; |
|
75 |
private const uint SHGFI_SHELLICONSIZE = 0x000000004; |
|
76 |
private const uint SHGFI_PIDL = 0x000000008; |
|
77 |
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; |
|
78 |
} |
SmartUpdate/IntSecurity.cs | ||
---|---|---|
1 |
namespace System.Drawing |
|
2 |
{ |
|
3 |
using System; |
|
4 |
using System.IO; |
|
5 |
using System.Security; |
|
6 |
using System.Security.Permissions; |
|
7 |
using System.Drawing.Printing; |
|
8 |
using System.Runtime.Versioning; |
|
9 |
|
|
10 |
internal static class IntSecurity |
|
11 |
{ |
|
12 |
private static readonly UIPermission AllWindows = new UIPermission(UIPermissionWindow.AllWindows); |
|
13 |
private static readonly UIPermission SafeSubWindows = new UIPermission(UIPermissionWindow.SafeSubWindows); |
|
14 |
|
|
15 |
public static readonly CodeAccessPermission UnmanagedCode = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); |
|
16 |
|
|
17 |
public static readonly CodeAccessPermission ObjectFromWin32Handle = UnmanagedCode; |
|
18 |
public static readonly CodeAccessPermission Win32HandleManipulation = UnmanagedCode; |
|
19 |
|
|
20 |
public static readonly PrintingPermission NoPrinting = new PrintingPermission(PrintingPermissionLevel.NoPrinting); |
|
21 |
public static readonly PrintingPermission SafePrinting = new PrintingPermission(PrintingPermissionLevel.SafePrinting); |
|
22 |
public static readonly PrintingPermission DefaultPrinting = new PrintingPermission(PrintingPermissionLevel.DefaultPrinting); |
|
23 |
public static readonly PrintingPermission AllPrinting = new PrintingPermission(PrintingPermissionLevel.AllPrinting); |
|
24 |
|
|
25 |
[ResourceExposure(ResourceScope.None)] |
|
26 |
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] |
|
27 |
internal static void DemandReadFileIO(string fileName) |
|
28 |
{ |
|
29 |
string full = fileName; |
|
30 |
|
|
31 |
full = UnsafeGetFullPath(fileName); |
|
32 |
|
|
33 |
new FileIOPermission(FileIOPermissionAccess.Read, full).Demand(); |
|
34 |
} |
|
35 |
|
|
36 |
[ResourceExposure(ResourceScope.None)] |
|
37 |
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] |
|
38 |
internal static void DemandWriteFileIO(string fileName) |
|
39 |
{ |
|
40 |
string full = fileName; |
|
41 |
|
|
42 |
full = UnsafeGetFullPath(fileName); |
|
43 |
|
|
44 |
new FileIOPermission(FileIOPermissionAccess.Write, full).Demand(); |
|
45 |
} |
|
46 |
|
|
47 |
[ResourceExposure(ResourceScope.Machine)] |
|
48 |
[ResourceConsumption(ResourceScope.Machine)] |
|
49 |
internal static string UnsafeGetFullPath(string fileName) |
|
50 |
{ |
|
51 |
string full = fileName; |
|
52 |
|
|
53 |
FileIOPermission fiop = new FileIOPermission(PermissionState.None); |
|
54 |
fiop.AllFiles = FileIOPermissionAccess.PathDiscovery; |
|
55 |
fiop.Assert(); |
|
56 |
|
|
57 |
try |
|
58 |
{ |
|
59 |
full = Path.GetFullPath(fileName); |
|
60 |
} |
|
61 |
finally |
|
62 |
{ |
|
63 |
CodeAccessPermission.RevertAssert(); |
|
64 |
} |
|
65 |
|
|
66 |
return full; |
|
67 |
} |
|
68 |
|
|
69 |
static PermissionSet allPrintingAndUnmanagedCode; |
|
70 |
public static PermissionSet AllPrintingAndUnmanagedCode |
|
71 |
{ |
|
72 |
get |
|
73 |
{ |
|
74 |
if (allPrintingAndUnmanagedCode == null) |
|
75 |
{ |
|
76 |
PermissionSet temp = new PermissionSet(PermissionState.None); |
|
77 |
temp.SetPermission(IntSecurity.UnmanagedCode); |
|
78 |
temp.SetPermission(IntSecurity.AllPrinting); |
|
79 |
allPrintingAndUnmanagedCode = temp; |
|
80 |
} |
|
81 |
return allPrintingAndUnmanagedCode; |
|
82 |
} |
|
83 |
} |
|
84 |
|
|
85 |
internal static bool HasPermission(PrintingPermission permission) |
|
86 |
{ |
|
87 |
try |
|
88 |
{ |
|
89 |
permission.Demand(); |
|
90 |
return true; |
|
91 |
} |
|
92 |
catch (SecurityException) |
|
93 |
{ |
|
94 |
return false; |
|
95 |
} |
|
96 |
} |
|
97 |
} |
|
98 |
} |
SmartUpdate/MainWindow.xaml | ||
---|---|---|
1 |
<Window x:Class="SmartUpdate.MainWindow" |
|
2 |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
3 |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
4 |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|
5 |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|
6 |
xmlns:local="clr-namespace:SmartUpdate" |
|
7 |
mc:Ignorable="d" |
|
8 |
WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="CanResizeWithGrip" AllowsTransparency="True" |
|
9 |
Title="MARKUS SmartUpdate" Height="450" Width="600"> |
|
10 |
|
|
11 |
|
|
12 |
<Border Name="main" BorderThickness="1" BorderBrush="LightGray" Margin="0"> |
|
13 |
<DockPanel> |
|
14 |
<Border Name="border" DockPanel.Dock="Top" Height="25" Background="#FF2A579A"> |
|
15 |
<Grid> |
|
16 |
<TextBlock Text="Markus SmartUpdate" Foreground="White" Margin="100,0,100,4" HorizontalAlignment="Center" VerticalAlignment="Bottom" x:Name="TitleText"/> |
|
17 |
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Stretch"> |
|
18 |
<Image Visibility="Visible" Source="Resources/minimize-window.png" Width="24" Height="24" MouseDown="WinState" x:Name="Win_min"/> |
|
19 |
<Image Visibility="Visible" Source="Resources/maximize-window.png" Width="24" Height="24" MouseDown="WinState" x:Name="Win_max"/> |
|
20 |
<Image Visibility="Visible" Source="Resources/close-window.png" Width="24" Height="24" MouseDown="WinState" x:Name="Win_Close"/> |
|
21 |
</StackPanel> |
|
22 |
</Grid> |
|
23 |
</Border> |
|
24 |
<Grid Margin="0,0,0,0" Background="WhiteSmoke"> |
|
25 |
|
|
26 |
<!--<ProgressBar Name="TotalDownloadProgressBar" HorizontalAlignment="Center" Height="30" VerticalAlignment="Top" Width="500" Margin="46,330,46,0" />--> |
|
27 |
<ProgressBar Name="PartialDownloadProgressBar" HorizontalAlignment="Center" Height="30" VerticalAlignment="Top" Width="500" Margin="46,362,46,0"/> |
|
28 |
<TextBlock Text="{Binding ElementName=PartialDownloadProgressBar, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,369,0,0"/> |
|
29 |
<ListView HorizontalAlignment="Left" Height="236" Margin="46,103,0,0" VerticalAlignment="Top" Width="500" Name="downloadlist"> |
|
30 |
|
|
31 |
<ListView.View> |
|
32 |
<GridView> |
|
33 |
<!--<GridViewColumn Header="Num" Width="40" DisplayMemberBinding="{Binding Num}" />--> |
|
34 |
|
|
35 |
<GridViewColumn Width="310" Header="FileName" > |
|
36 |
<GridViewColumn.CellTemplate> |
|
37 |
<DataTemplate> |
|
38 |
<StackPanel Orientation="Horizontal"> |
|
39 |
<Image Source="{Binding SIcon}" Width="24" Height="24"></Image> |
|
40 |
<!--<Image Source="{Binding SIcon}" Width="24" Height="24"></Image>--> |
|
41 |
<TextBlock Text="{Binding FileName}"/> |
|
42 |
</StackPanel> |
|
43 |
</DataTemplate> |
|
44 |
|
|
45 |
</GridViewColumn.CellTemplate> |
|
46 |
|
|
47 |
</GridViewColumn> |
|
48 |
|
|
49 |
<!-- <GridViewColumn Header="FileName" Width="260" DisplayMemberBinding="{Binding FileName}" /> --> |
|
50 |
|
|
51 |
<GridViewColumn Header="Version" Width="179" DisplayMemberBinding="{Binding Version}" /> |
|
52 |
<!--<GridViewColumn Header="Date" Width="100" DisplayMemberBinding="{Binding Date}" />--> |
|
53 |
</GridView> |
|
54 |
|
|
55 |
</ListView.View> |
|
56 |
</ListView> |
|
57 |
<Rectangle Fill="#FFFFFF" HorizontalAlignment="Center" Height="70" Stroke="LightGray" VerticalAlignment="Top" Width="596" Margin="0,1,0,0"/> |
|
58 |
|
|
59 |
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Height="50" Width="400" Margin="15,15,15,15"> |
|
60 |
<Run FontWeight="Bold" FontStyle="Italic" FontSize="14" Text="MARKUS Update...." /><LineBreak /> |
|
61 |
<Run FontStyle="Italic" FontSize="12" Text=" 업데이트 중입니다. 잠시만 기다려주세요... " /> |
|
62 |
</TextBlock> |
|
63 |
<Image HorizontalAlignment="Left" Height="64" Margin="525,4,0,0" VerticalAlignment="Top" Width="70" Source="Resources/UpdateImg.png"/> |
|
64 |
|
|
65 |
<!--<Separator Margin="0,0,0,0"/>--> |
|
66 |
<!-- <TextBox FontSize="18" Text ="MARKUS SmartUpdate" Margin="200,67,200,0" HorizontalAlignment="Center" VerticalAlignment="Top"/>--> |
|
67 |
</Grid> |
|
68 |
</DockPanel> |
|
69 |
</Border> |
|
70 |
|
|
71 |
|
|
72 |
</Window> |
SmartUpdate/MainWindow.xaml.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.ComponentModel; |
|
4 |
using System.Diagnostics; |
|
5 |
using System.IO; |
|
6 |
using System.Net; |
|
7 |
using System.Threading; |
|
8 |
using System.Windows; |
|
9 |
using System.Windows.Controls; |
|
10 |
using System.Windows.Input; |
|
11 |
using System.Xml; |
|
12 |
using System.Drawing; |
|
13 |
using System.Windows.Media; |
|
14 |
using Image = System.Windows.Controls.Image; |
|
15 |
using System.Windows.Media.Imaging; |
|
16 |
using System.Text; |
|
17 |
using System.Runtime.InteropServices; |
|
18 |
using System.Security; |
|
19 |
|
|
20 |
namespace SmartUpdate |
|
21 |
{ |
|
22 |
/// <summary> |
|
23 |
/// MainWindow.xaml에 대한 상호 작용 논리 |
|
24 |
/// </summary> |
|
25 |
public partial class MainWindow : Window |
|
26 |
{ |
|
27 |
private int index = 0; //업데이트시 파일 하나씩 넘어가게 하기 위해서 |
|
28 |
private bool check = false; //다운완료된것 체크 |
|
29 |
private int lastIndex; |
|
30 |
private Thread theProgBarThread; |
|
31 |
private bool m_bLoop; |
|
32 |
private string versionPath = null; //64, 86 버전에 따른 서버 파일 위치 |
|
33 |
private string[] strArg; //KCOM 접속 파라미터 값 받기 위해 |
|
34 |
private int c_index = 1; //마지막 파일 확인 후 종료하기 위해 |
|
35 |
private string msgFileName = SmartUpdate.Properties.Settings.Default.msgFileName; //메시지창에 띄워줄 프로그램명 |
|
36 |
private string FileName = SmartUpdate.Properties.Settings.Default.FileName; //실행파일명 |
|
37 |
|
|
38 |
public MainWindow() |
|
39 |
{ |
|
40 |
InitializeComponent(); |
|
41 |
WindowStartupLocation = WindowStartupLocation.CenterOwner; //창 가운데로 |
|
42 |
WindowStartupLocation = WindowStartupLocation.CenterScreen; //창 가운데로 |
|
43 |
Topmost = true; //창 최상위로 |
|
44 |
this.Loaded += new RoutedEventHandler(MainWindow_Loaded); |
|
45 |
} |
|
46 |
|
|
47 |
void MainWindow_Loaded(object sender, RoutedEventArgs e) |
|
48 |
{ |
|
49 |
m_bLoop = true; |
|
50 |
lastIndex = index = 0; |
|
51 |
theProgBarThread = new Thread(new ThreadStart(Step)); |
|
52 |
theProgBarThread.Start(); |
|
53 |
Thread.Sleep(100); |
|
54 |
PartialDownloadProgressBar.Maximum = 100; |
|
55 |
strArg = Environment.GetCommandLineArgs(); //KCOM 접속 파라미터 값 받기 위해 |
|
56 |
ConnectUpgradeServer(); //여기서부터 XML 파싱 및 파일 다운로드 |
|
57 |
} |
|
58 |
|
|
59 |
public class ItemInfo |
|
60 |
{ |
|
61 |
public string FileName { get; set; } |
|
62 |
public string Version { get; set; } |
|
63 |
public ImageSource SIcon { get; set; } |
|
64 |
} |
|
65 |
|
|
66 |
List<ItemInfo> itemInfoList = new List<ItemInfo>(); |
|
67 |
List<ItemInfo> downloadList = new List<ItemInfo>(); |
|
68 |
|
|
69 |
private void SetXmlParseing() |
|
70 |
{ |
|
71 |
try |
|
72 |
{ |
|
73 |
XmlDocument xdoc = new XmlDocument(); |
|
74 |
if (Environment.Is64BitProcess == true) //64 bit machine |
|
75 |
{ |
|
76 |
versionPath = SmartUpdate.Properties.Settings.Default.UpdateVer64; |
|
77 |
} |
|
78 |
else //32 bit machine |
|
79 |
{ |
|
80 |
versionPath = SmartUpdate.Properties.Settings.Default.UpdateVer86; |
|
81 |
} |
|
82 |
// XML 데이타를 파일에서 로드 |
|
83 |
xdoc.Load(versionPath); |
|
84 |
// 특정 노드들을 필터링 |
|
85 |
XmlNodeList nodes = xdoc.SelectNodes("/RootElement/Item"); |
|
86 |
|
|
87 |
foreach (XmlNode emp in nodes) |
|
88 |
{ |
|
89 |
string Filename = emp.SelectSingleNode("Filename").InnerText; |
|
90 |
string Version = emp.SelectSingleNode("Version").InnerText; |
|
91 |
|
|
92 |
try |
|
93 |
{ |
|
94 |
//해당 파일이 서버에 있는지 확인 |
|
95 |
HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(Filename); |
|
96 |
HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); |
|
97 |
webres.Close(); |
|
98 |
webreq = null; |
|
99 |
webres = null; |
|
100 |
|
|
101 |
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + @Path.GetFileName(Filename))) //해당 파일이 클라이언트에 있는가? |
|
102 |
{ |
|
103 |
if (IsAccessAble(AppDomain.CurrentDomain.BaseDirectory + @Path.GetFileName(Filename)) == false) //다운받으려는 파일이 다른곳에서 점유중인지 확인. |
|
104 |
{ |
|
105 |
ErrorLogFileWrite("실행중인 파일로 인해 업데이트 실패 : " + @Path.GetFileName(Filename)); |
|
106 |
SmartUpdateExit("실행중인 "+ msgFileName + "가 있습니다. \n모두 닫은 후 다시 실행해주세요."); //스마트 업데이트 종료 |
|
107 |
} |
|
108 |
else if (FileVersionInfo.GetVersionInfo(AppDomain.CurrentDomain.BaseDirectory + @Path.GetFileName(Filename)).FileVersion != Version) //두개의 버전이 다른가? |
|
109 |
{ |
|
110 |
itemInfoList.Add(new ItemInfo() { FileName = Filename, Version = Version }); |
|
111 |
ImageSource icon = IconManager.GetIcon(@Path.GetFileName(Filename), false, false); |
|
112 |
downloadList.Add(new ItemInfo() { FileName = @Path.GetFileName(Filename), Version = Version, SIcon = icon }); |
|
113 |
} |
|
114 |
} |
|
115 |
else |
|
116 |
{ |
|
117 |
itemInfoList.Add(new ItemInfo() { FileName = Filename, Version = Version }); |
|
118 |
ImageSource icon = IconManager.GetIcon(@Path.GetFileName(Filename), false, false); |
|
119 |
downloadList.Add(new ItemInfo() { FileName = @Path.GetFileName(Filename), Version = Version, SIcon = icon }); |
|
120 |
} |
|
121 |
} |
|
122 |
catch(Exception ex) //다운로드 받아야할 파일이 서버에 없을 경우 스마트업데이트 강제 종료. |
|
123 |
{ |
|
124 |
ErrorLogFileWrite("Err : " + ex); |
|
125 |
SmartUpdateExit("서버에 파일이 없습니다."); |
|
126 |
} |
|
127 |
} |
|
128 |
|
|
129 |
downloadlist.ItemsSource = downloadList; |
|
130 |
SetDown(); |
|
131 |
} |
|
132 |
catch(Exception ex) //version.xml 파일이 없을 경우 스마트업데이트 강제 종료. |
|
133 |
{ |
|
134 |
ErrorLogFileWrite("Err : " + ex); |
|
135 |
SmartUpdateExit("File Loading Error SmartUpdate를 종료합니다."); //스마트 업데이트 종료 |
|
136 |
} |
|
137 |
} |
|
138 |
|
|
139 |
private void SetDown() |
|
140 |
{ |
|
141 |
try |
|
142 |
{ |
|
143 |
for (int i = 0; i < itemInfoList.Count; i++) |
|
144 |
{ |
|
145 |
WebClient theDownloadThread = new WebClient(); |
|
146 |
Uri url = new Uri(itemInfoList[i].FileName); |
|
147 |
theDownloadThread.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged); |
|
148 |
theDownloadThread.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); |
|
149 |
string filename = Path.GetFileName(itemInfoList[i].FileName); |
|
150 |
theDownloadThread.DownloadFileAsync(url, AppDomain.CurrentDomain.BaseDirectory + filename); |
|
151 |
|
|
152 |
} |
|
153 |
} |
|
154 |
catch(Exception ee) //다운로드 도중 에러시 스마트업데이트 강제 종료. |
|
155 |
{ |
|
156 |
ErrorLogFileWrite("SetDown() \r\n 상세로그 : " + ee); |
|
157 |
SmartUpdateExit("File Download Error SmartUpdate를 종료합니다."); //스마트 업데이트 종료 |
|
158 |
} |
|
159 |
} |
|
160 |
|
|
161 |
private void ConnectUpgradeServer() |
|
162 |
{ |
|
163 |
try |
|
164 |
{ |
|
165 |
SetXmlParseing(); |
|
166 |
} |
|
167 |
catch (Exception er) |
|
168 |
{ |
|
169 |
string strError = er.ToString(); |
|
170 |
MarkusStart(strError); |
|
171 |
} |
|
172 |
} |
|
173 |
|
|
174 |
|
|
175 |
private void MarkusStart(string MessageStr) |
|
176 |
{ |
|
177 |
try |
|
178 |
{ |
|
179 |
ErrorLogFileWrite("상세로그 : " + MessageStr); |
|
180 |
|
|
181 |
ProcessStartInfo proInfo = new ProcessStartInfo(); |
|
182 |
proInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + FileName; |
|
183 |
if (strArg.Length > 1) |
|
184 |
{ |
|
185 |
proInfo.Arguments = strArg[1]; |
|
186 |
} |
|
187 |
Process.Start(proInfo); |
|
188 |
|
|
189 |
//현재 실행되고 있는 자기 자신 프로세스의 정보 |
|
190 |
Process proc = Process.GetCurrentProcess(); |
|
191 |
proc.Kill(); |
|
192 |
} |
|
193 |
catch (Exception ee) |
|
194 |
{ |
|
195 |
ErrorLogFileWrite("Err로그 : " + ee); |
|
196 |
//MessageBox.Show(ee + "MARKUS를 재실행 해주시기 바랍니다."); |
|
197 |
} |
|
198 |
} |
|
199 |
|
|
200 |
private void SmartUpdateExit(string MessageStr) |
|
201 |
{ |
|
202 |
try |
|
203 |
{ |
|
204 |
MessageBox.Show(MessageStr, "종료합니다.", MessageBoxButton.OK); |
|
205 |
//현재 실행되고 있는 자기 자신 프로세스의 정보 |
|
206 |
Process proc = Process.GetCurrentProcess(); |
|
207 |
proc.Kill(); |
|
208 |
} |
|
209 |
catch (Exception ex) |
|
210 |
{ |
|
211 |
ErrorLogFileWrite("SmartUpdateExit() \r\n 상세로그 : " + MessageStr); |
|
212 |
} |
|
213 |
} |
|
214 |
|
|
215 |
|
|
216 |
//http://blog.naver.com/PostView.nhn?blogId=nersion&logNo=140150987526&parentCategoryNo=&categoryNo=56&viewDate=&isShowPopularPosts=true&from=search |
|
217 |
private bool IsAccessAble(String path) |
|
218 |
{ |
|
219 |
FileStream fs = null; |
|
220 |
try |
|
221 |
{ |
|
222 |
//앞단에서 파일이 있는 경우에만 타도록 했음 그렇지 않으면 파일 자체가 없을때도 false 반환 |
|
223 |
fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None); |
|
224 |
} |
|
225 |
catch (IOException) |
|
226 |
{ |
|
227 |
//에러가 발생한 이유는 이미 다른 프로세서에서 점유중. |
|
228 |
return false; |
|
229 |
} |
|
230 |
finally |
|
231 |
{ |
|
232 |
if (fs != null) |
|
233 |
{ |
|
234 |
//만약에 파일이 정상적으로 열렸다면 점유중이 아니다. |
|
235 |
//다시 파일을 닫아줘야 한다. |
|
236 |
fs.Close(); |
|
237 |
} |
|
238 |
} |
|
239 |
return true; |
|
240 |
} |
|
241 |
|
|
242 |
protected XmlNode CreateNode(XmlDocument xmlDoc, string name, string innerXml) |
|
243 |
{ |
|
244 |
XmlNode node = xmlDoc.CreateElement(string.Empty, name, string.Empty); |
|
245 |
node.InnerXml = innerXml; |
|
246 |
|
|
247 |
return node; |
|
248 |
} |
|
249 |
|
|
250 |
private void Step() |
|
251 |
{ |
|
252 |
while (m_bLoop) |
|
253 |
{ |
|
254 |
if (lastIndex < index) |
|
255 |
{ |
|
256 |
lastIndex++; |
|
257 |
} |
|
258 |
Thread.Sleep(1000); |
|
259 |
} |
|
260 |
} |
|
261 |
|
|
262 |
private void Completed(object sender, AsyncCompletedEventArgs e) |
|
263 |
{ |
|
264 |
c_index++; |
|
265 |
if (c_index > itemInfoList.Count) |
|
266 |
{ |
|
267 |
try |
|
268 |
{ |
|
269 |
ProcessStartInfo proInfo = new ProcessStartInfo(); |
|
270 |
proInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + FileName; |
|
271 |
|
|
272 |
if (strArg.Length > 1) |
|
273 |
{ |
|
274 |
proInfo.Arguments = strArg[1]; |
|
275 |
} |
|
276 |
Process.Start(proInfo); |
|
277 |
|
|
278 |
//현재 실행되고 있는 자기 자신 프로세스의 정보 |
|
279 |
Process proc = Process.GetCurrentProcess(); |
|
280 |
proc.Kill(); |
|
281 |
} |
|
282 |
catch (Exception ee) |
|
283 |
{ |
|
284 |
ErrorLogFileWrite("SmartUpdate 종료 또는 "+ msgFileName + "실행에 실패했습니다. \r\n 상세로그 : " + ee); |
|
285 |
//MessageBox.Show(strArg[1] + "MARKUS를 재실행 해주시기 바랍니다."); |
|
286 |
} |
|
287 |
} |
|
288 |
|
|
289 |
} |
|
290 |
|
|
291 |
//파일 다운로드 상황을 반영한다. |
|
292 |
private void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) |
|
293 |
{ |
|
294 |
//PartialDownloadProgressBar.Value = e.ProgressPercentage; |
|
295 |
//이전에 다운로드 받은 파일이 완료되었다면 |
|
296 |
if (e.TotalBytesToReceive == e.BytesReceived && !check) |
|
297 |
{ |
|
298 |
if (index < itemInfoList.Count) |
|
299 |
{ |
|
300 |
index++; |
|
301 |
PartialDownloadProgressBar.Value = (Convert.ToDouble(index) / Convert.ToDouble(itemInfoList.Count)) * 100; |
|
302 |
LogFileWrite(); |
|
303 |
} |
|
304 |
} |
|
305 |
else |
|
306 |
{ |
|
307 |
check = false; |
|
308 |
} |
|
309 |
} |
|
310 |
|
|
311 |
private void ErrorLogFileWrite(string Err) |
|
312 |
{ |
|
313 |
try |
|
314 |
{ |
|
315 |
string pathString = AppDomain.CurrentDomain.BaseDirectory + "UpdateLog\\Err"; |
|
316 |
if (!File.Exists(pathString)) |
|
317 |
{ |
|
318 |
Directory.CreateDirectory(pathString); |
|
319 |
} |
|
320 |
|
|
321 |
Err = Err + " " +DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "\r\n"; |
|
322 |
string path = pathString + "\\" + "UpdateErrLog_" + DateTime.Now.ToString("yyyy-MM-dd hh-mm") + ".txt"; |
|
323 |
File.AppendAllText(path, Err); |
|
324 |
} |
|
325 |
catch (Exception er) |
|
326 |
{ |
|
327 |
string strError = er.ToString(); |
|
328 |
//MessageBox.Show("err : " + er); |
|
329 |
} |
|
330 |
} |
|
331 |
private void LogFileWrite() |
|
332 |
{ |
|
333 |
try |
|
334 |
{ |
|
335 |
string pathString = AppDomain.CurrentDomain.BaseDirectory + "UpdateLog"; |
|
336 |
if (!File.Exists(pathString)) |
|
337 |
{ |
|
338 |
Directory.CreateDirectory(pathString); |
|
339 |
} |
|
340 |
|
|
341 |
FileStream fs = new FileStream(pathString + "\\UpdateLog_" + DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss") + ".txt", FileMode.OpenOrCreate, FileAccess.Write); |
|
342 |
StreamWriter sw = new StreamWriter(fs); |
|
343 |
sw.WriteLine("<업그레이드 정보>"); |
|
344 |
sw.WriteLine("<업데이트 날짜>"); |
|
345 |
sw.WriteLine("{0}", DateTime.Today.ToLongDateString()); |
|
346 |
sw.WriteLine("<업데이트 파일>"); |
|
347 |
for (int i = 0; i < itemInfoList.Count; i++) |
|
348 |
sw.WriteLine("{0}", itemInfoList[i].FileName); |
|
349 |
|
|
350 |
sw.Close(); |
|
351 |
fs.Close(); |
|
352 |
} |
|
353 |
catch (Exception er) |
|
354 |
{ |
|
355 |
string strError = er.ToString(); |
|
356 |
ErrorLogFileWrite("업데이트 파일 작성에 실패했습니다. \r\n 상세로그 : " + strError); |
|
357 |
} |
|
358 |
} |
|
359 |
|
|
360 |
private void WinState(object sender, MouseButtonEventArgs e) |
|
361 |
{ |
|
362 |
switch ((e.Source as Image).Name) |
|
363 |
{ |
|
364 |
case ("Win_min"): |
|
365 |
{ |
|
366 |
WindowState = WindowState.Minimized; |
|
367 |
} |
|
368 |
break; |
|
369 |
case ("Win_max"): |
|
370 |
{ |
|
371 |
if (WindowState == WindowState.Maximized) |
|
372 |
{ |
|
373 |
WindowState = WindowState.Normal; |
|
374 |
} |
|
375 |
else |
|
376 |
{ |
|
377 |
WindowState = WindowState.Maximized; |
|
378 |
} |
|
379 |
} |
|
380 |
break; |
|
381 |
case ("Win_Close"): |
|
382 |
{ |
|
383 |
|
|
384 |
this.Close(); |
|
385 |
} |
|
386 |
break; |
|
387 |
} |
|
388 |
} |
|
389 |
} |
|
390 |
} |
SmartUpdate/Properties/AssemblyInfo.cs | ||
---|---|---|
1 |
using System.Reflection; |
|
2 |
using System.Resources; |
|
3 |
using System.Runtime.CompilerServices; |
|
4 |
using System.Runtime.InteropServices; |
|
5 |
using System.Windows; |
|
6 |
|
|
7 |
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 |
|
8 |
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 |
|
9 |
// 이러한 특성 값을 변경하세요. |
|
10 |
[assembly: AssemblyTitle("SmartUpdate")] |
|
11 |
[assembly: AssemblyDescription("")] |
|
12 |
[assembly: AssemblyConfiguration("")] |
|
13 |
[assembly: AssemblyCompany("")] |
|
14 |
[assembly: AssemblyProduct("SmartUpdate")] |
|
15 |
[assembly: AssemblyCopyright("Copyright © 2018")] |
|
16 |
[assembly: AssemblyTrademark("")] |
|
17 |
[assembly: AssemblyCulture("")] |
|
18 |
|
|
19 |
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 |
|
20 |
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 |
|
21 |
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. |
|
22 |
[assembly: ComVisible(false)] |
|
23 |
|
|
24 |
//지역화 가능 응용 프로그램 빌드를 시작하려면 다음을 설정하세요. |
|
25 |
//.csproj 파일에서 <PropertyGroup> 내에 <UICulture>CultureYouAreCodingWith</UICulture>를 |
|
26 |
//설정하십시오. 예를 들어 소스 파일에서 영어(미국)를 |
|
27 |
//사용하는 경우 <UICulture>를 en-US로 설정합니다. 그런 다음 아래 |
|
28 |
//NeutralResourceLanguage 특성의 주석 처리를 제거합니다. 아래 줄의 "en-US"를 업데이트하여 |
|
29 |
//프로젝트 파일의 UICulture 설정과 일치시킵니다. |
|
30 |
|
|
31 |
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] |
|
32 |
|
|
33 |
|
|
34 |
[assembly: ThemeInfo( |
|
35 |
ResourceDictionaryLocation.None, //테마별 리소스 사전의 위치 |
|
36 |
//(페이지 또는 응용 프로그램 리소스 사진에 |
|
37 |
// 리소스가 없는 경우에 사용됨) |
|
38 |
ResourceDictionaryLocation.SourceAssembly //제네릭 리소스 사전의 위치 |
|
39 |
//(페이지 또는 응용 프로그램 리소스 사진에 |
|
40 |
// 리소스가 없는 경우에 사용됨) |
|
41 |
)] |
|
42 |
|
|
43 |
|
|
44 |
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. |
|
45 |
// |
|
46 |
// 주 버전 |
|
47 |
// 부 버전 |
|
48 |
// 빌드 번호 |
|
49 |
// 수정 버전 |
|
50 |
// |
|
51 |
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호가 자동으로 |
|
52 |
// 지정되도록 할 수 있습니다. |
|
53 |
// [assembly: AssemblyVersion("1.0.*")] |
|
54 |
[assembly: AssemblyVersion("1.0.0.0")] |
|
55 |
[assembly: AssemblyFileVersion("1.0.0.0")] |
SmartUpdate/Properties/Resources.Designer.cs | ||
---|---|---|
1 |
//------------------------------------------------------------------------------ |
|
2 |
// <auto-generated> |
|
3 |
// 이 코드는 도구를 사용하여 생성되었습니다. |
|
4 |
// 런타임 버전:4.0.30319.42000 |
|
5 |
// |
|
6 |
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 |
|
7 |
// 이러한 변경 내용이 손실됩니다. |
|
8 |
// </auto-generated> |
|
9 |
//------------------------------------------------------------------------------ |
|
10 |
|
|
11 |
namespace SmartUpdate.Properties { |
|
12 |
using System; |
|
13 |
|
|
14 |
|
|
15 |
/// <summary> |
|
16 |
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. |
|
17 |
/// </summary> |
|
18 |
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder |
|
19 |
// 클래스에서 자동으로 생성되었습니다. |
|
20 |
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을 |
|
21 |
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. |
|
22 |
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] |
|
23 |
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
|
24 |
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
|
25 |
internal class Resources { |
|
26 |
|
|
27 |
private static global::System.Resources.ResourceManager resourceMan; |
|
28 |
|
|
29 |
private static global::System.Globalization.CultureInfo resourceCulture; |
|
30 |
|
|
31 |
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
|
32 |
internal Resources() { |
|
33 |
} |
|
34 |
|
|
35 |
/// <summary> |
|
36 |
/// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. |
|
37 |
/// </summary> |
|
38 |
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
|
39 |
internal static global::System.Resources.ResourceManager ResourceManager { |
|
40 |
get { |
|
41 |
if (object.ReferenceEquals(resourceMan, null)) { |
|
42 |
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SmartUpdate.Properties.Resources", typeof(Resources).Assembly); |
|
43 |
resourceMan = temp; |
|
44 |
} |
|
45 |
return resourceMan; |
|
46 |
} |
|
47 |
} |
|
48 |
|
|
49 |
/// <summary> |
|
50 |
/// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을 |
|
51 |
/// 재정의합니다. |
|
52 |
/// </summary> |
|
53 |
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
|
54 |
internal static global::System.Globalization.CultureInfo Culture { |
|
55 |
get { |
|
56 |
return resourceCulture; |
|
57 |
} |
|
58 |
set { |
|
59 |
resourceCulture = value; |
|
60 |
} |
|
61 |
} |
|
62 |
} |
|
63 |
} |
SmartUpdate/Properties/Resources.resx | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<root> |
|
3 |
<!-- |
|
4 |
Microsoft ResX Schema |
|
5 |
|
|
6 |
Version 2.0 |
|
7 |
|
|
8 |
The primary goals of this format is to allow a simple XML format |
|
9 |
that is mostly human readable. The generation and parsing of the |
|
10 |
various data types are done through the TypeConverter classes |
|
11 |
associated with the data types. |
|
12 |
|
|
13 |
Example: |
|
14 |
|
|
15 |
... ado.net/XML headers & schema ... |
|
16 |
<resheader name="resmimetype">text/microsoft-resx</resheader> |
|
17 |
<resheader name="version">2.0</resheader> |
|
18 |
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
|
19 |
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
|
20 |
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
|
21 |
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
|
22 |
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
|
23 |
<value>[base64 mime encoded serialized .NET Framework object]</value> |
|
24 |
</data> |
|
25 |
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
|
26 |
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
|
27 |
<comment>This is a comment</comment> |
|
28 |
</data> |
|
29 |
|
|
30 |
There are any number of "resheader" rows that contain simple |
|
31 |
name/value pairs. |
|
32 |
|
|
33 |
Each data row contains a name, and value. The row also contains a |
|
34 |
type or mimetype. Type corresponds to a .NET class that support |
|
35 |
text/value conversion through the TypeConverter architecture. |
|
36 |
Classes that don't support this are serialized and stored with the |
|
37 |
mimetype set. |
|
38 |
|
|
39 |
The mimetype is used for serialized objects, and tells the |
|
40 |
ResXResourceReader how to depersist the object. This is currently not |
|
41 |
extensible. For a given mimetype the value must be set accordingly: |
|
42 |
|
|
43 |
Note - application/x-microsoft.net.object.binary.base64 is the format |
|
44 |
that the ResXResourceWriter will generate, however the reader can |
|
45 |
read any of the formats listed below. |
|
46 |
|
|
47 |
mimetype: application/x-microsoft.net.object.binary.base64 |
|
48 |
value : The object must be serialized with |
|
49 |
: System.Serialization.Formatters.Binary.BinaryFormatter |
|
50 |
: and then encoded with base64 encoding. |
|
51 |
|
|
52 |
mimetype: application/x-microsoft.net.object.soap.base64 |
|
53 |
value : The object must be serialized with |
|
54 |
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
|
55 |
: and then encoded with base64 encoding. |
|
56 |
|
|
57 |
mimetype: application/x-microsoft.net.object.bytearray.base64 |
|
58 |
value : The object must be serialized into a byte array |
|
59 |
: using a System.ComponentModel.TypeConverter |
|
60 |
: and then encoded with base64 encoding. |
|
61 |
--> |
|
62 |
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
|
63 |
<xsd:element name="root" msdata:IsDataSet="true"> |
|
64 |
<xsd:complexType> |
|
65 |
<xsd:choice maxOccurs="unbounded"> |
|
66 |
<xsd:element name="metadata"> |
|
67 |
<xsd:complexType> |
|
68 |
<xsd:sequence> |
|
69 |
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
|
70 |
</xsd:sequence> |
|
71 |
<xsd:attribute name="name" type="xsd:string" /> |
|
72 |
<xsd:attribute name="type" type="xsd:string" /> |
|
73 |
<xsd:attribute name="mimetype" type="xsd:string" /> |
|
74 |
</xsd:complexType> |
|
75 |
</xsd:element> |
|
76 |
<xsd:element name="assembly"> |
|
77 |
<xsd:complexType> |
|
78 |
<xsd:attribute name="alias" type="xsd:string" /> |
|
79 |
<xsd:attribute name="name" type="xsd:string" /> |
|
80 |
</xsd:complexType> |
|
81 |
</xsd:element> |
|
82 |
<xsd:element name="data"> |
|
83 |
<xsd:complexType> |
|
84 |
<xsd:sequence> |
|
85 |
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
|
86 |
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
|
87 |
</xsd:sequence> |
|
88 |
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
|
89 |
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
|
90 |
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
|
91 |
</xsd:complexType> |
|
92 |
</xsd:element> |
|
93 |
<xsd:element name="resheader"> |
|
94 |
<xsd:complexType> |
|
95 |
<xsd:sequence> |
|
96 |
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
|
97 |
</xsd:sequence> |
|
98 |
<xsd:attribute name="name" type="xsd:string" use="required" /> |
|
99 |
</xsd:complexType> |
|
100 |
</xsd:element> |
|
101 |
</xsd:choice> |
|
102 |
</xsd:complexType> |
|
103 |
</xsd:element> |
|
104 |
</xsd:schema> |
|
105 |
<resheader name="resmimetype"> |
|
106 |
<value>text/microsoft-resx</value> |
|
107 |
</resheader> |
|
108 |
<resheader name="version"> |
|
109 |
<value>2.0</value> |
|
110 |
</resheader> |
|
111 |
<resheader name="reader"> |
|
112 |
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
내보내기 Unified diff