代码
1 frmMain.cs
2
3 using System;
4 using System.Drawing;
5 using System.Collections;
6 using System.ComponentModel;
7 using System.Windows.Forms;
8 using System.Data;
9
10 namespace Loki
11 {
12 /// <summary>
13 /// Summary description for Form1.
14 /// </summary>
15 public class frmMain : System.Windows.Forms.Form
16 {
17 public System.Windows.Forms.Button btnConvert;
18 public System.Windows.Forms.TextBox txtXMLFileName;
19 public System.Windows.Forms.Label Label2;
20 public System.Windows.Forms.TextBox txtIniFileName;
21 public System.Windows.Forms.Button btnClose;
22 public System.Windows.Forms.Label Label1;
23
24 /// <summary>
25 /// Required designer variable.
26 /// </summary>
27 private System.ComponentModel.Container components = null;
28
29 public frmMain()
30 {
31 //
32 // Required for Windows Form Designer support
33 //
34 InitializeComponent();
35 }
36
37 /// <summary>
38 /// Clean up any resources being used.
39 /// </summary>
40 protected override void Dispose( bool disposing )
41 {
42 if( disposing )
43 {
44 if (components != null)
45 {
46 components.Dispose();
47 }
48 }
49 base.Dispose( disposing );
50 }
51
52 #region Windows Form Designer generated code
53 /// <summary>
54 /// Required method for Designer support - do not modify
55 /// the contents of this method with the code editor.
56 /// </summary>
57 private void InitializeComponent()
58 {
59 this.btnConvert = new System.Windows.Forms.Button();
60 this.txtXMLFileName = new System.Windows.Forms.TextBox();
61 this.txtIniFileName = new System.Windows.Forms.TextBox();
62 this.Label1 = new System.Windows.Forms.Label();
63 this.btnClose = new System.Windows.Forms.Button();
64 this.Label2 = new System.Windows.Forms.Label();
65 this.SuspendLayout();
66 //
67 // btnConvert
68 //
69 this.btnConvert.BackColor = System.Drawing.SystemColors.Control;
70 this.btnConvert.Cursor = System.Windows.Forms.Cursors.Default;
71 this.btnConvert.Location = new System.Drawing.Point(160, 96);
72 this.btnConvert.Name = "btnConvert";
73 this.btnConvert.RightToLeft = System.Windows.Forms.RightToLeft.No;
74 this.btnConvert.Size = new System.Drawing.Size(105, 25);
75 this.btnConvert.TabIndex = 4;
76 this.btnConvert.Text = "&Convert";
77 this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click);
78 //
79 // txtXMLFileName
80 //
81 this.txtXMLFileName.AcceptsReturn = true;
82 this.txtXMLFileName.AutoSize = false;
83 this.txtXMLFileName.BackColor = System.Drawing.SystemColors.Window;
84 this.txtXMLFileName.Cursor = System.Windows.Forms.Cursors.IBeam;
85 this.txtXMLFileName.ForeColor = System.Drawing.SystemColors.WindowText;
86 this.txtXMLFileName.Location = new System.Drawing.Point(104, 48);
87 this.txtXMLFileName.MaxLength = 0;
88 this.txtXMLFileName.Name = "txtXMLFileName";
89 this.txtXMLFileName.RightToLeft = System.Windows.Forms.RightToLeft.No;
90 this.txtXMLFileName.Size = new System.Drawing.Size(273, 25);
91 this.txtXMLFileName.TabIndex = 3;
92 this.txtXMLFileName.Text = "";
93 //
94 // txtIniFileName
95 //
96 this.txtIniFileName.AcceptsReturn = true;
97 this.txtIniFileName.AutoSize = false;
98 this.txtIniFileName.BackColor = System.Drawing.SystemColors.Window;
99 this.txtIniFileName.Cursor = System.Windows.Forms.Cursors.IBeam;
100 this.txtIniFileName.ForeColor = System.Drawing.SystemColors.WindowText;
101 this.txtIniFileName.Location = new System.Drawing.Point(104, 16);
102 this.txtIniFileName.MaxLength = 0;
103 this.txtIniFileName.Name = "txtIniFileName";
104 this.txtIniFileName.RightToLeft = System.Windows.Forms.RightToLeft.No;
105 this.txtIniFileName.Size = new System.Drawing.Size(273, 25);
106 this.txtIniFileName.TabIndex = 1;
107 this.txtIniFileName.Text = "E:\\Source\\Loki\\INI2XML\\VB.NET\\projINI2XML.NET\\Sample.ini";
108 //
109 // Label1
110 //
111 this.Label1.AutoSize = true;
112 this.Label1.BackColor = System.Drawing.SystemColors.Control;
113 this.Label1.Cursor = System.Windows.Forms.Cursors.Default;
114 this.Label1.ForeColor = System.Drawing.SystemColors.ControlText;
115 this.Label1.Location = new System.Drawing.Point(16, 24);
116 this.Label1.Name = "Label1";
117 this.Label1.RightToLeft = System.Windows.Forms.RightToLeft.No;
118 this.Label1.Size = new System.Drawing.Size(68, 13);
119 this.Label1.TabIndex = 0;
120 this.Label1.Text = "INI Filename";
121 //
122 // btnClose
123 //
124 this.btnClose.BackColor = System.Drawing.SystemColors.Control;
125 this.btnClose.Cursor = System.Windows.Forms.Cursors.Default;
126 this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
127 this.btnClose.Location = new System.Drawing.Point(272, 96);
128 this.btnClose.Name = "btnClose";
129 this.btnClose.RightToLeft = System.Windows.Forms.RightToLeft.No;
130 this.btnClose.Size = new System.Drawing.Size(105, 25);
131 this.btnClose.TabIndex = 5;
132 this.btnClose.Text = "Close";
133 this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
134 //
135 // Label2
136 //
137 this.Label2.AutoSize = true;
138 this.Label2.BackColor = System.Drawing.SystemColors.Control;
139 this.Label2.Cursor = System.Windows.Forms.Cursors.Default;
140 this.Label2.ForeColor = System.Drawing.SystemColors.ControlText;
141 this.Label2.Location = new System.Drawing.Point(16, 56);
142 this.Label2.Name = "Label2";
143 this.Label2.RightToLeft = System.Windows.Forms.RightToLeft.No;
144 this.Label2.Size = new System.Drawing.Size(77, 13);
145 this.Label2.TabIndex = 2;
146 this.Label2.Text = "XML Filename";
147 //
148 // frmMain
149 //
150 this.AcceptButton = this.btnConvert;
151 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
152 this.CancelButton = this.btnClose;
153 this.ClientSize = new System.Drawing.Size(392, 141);
154 this.Controls.AddRange(new System.Windows.Forms.Control[] {
155 this.btnConvert,
156 this.txtXMLFileName,
157 this.Label2,
158 this.txtIniFileName,
159 this.btnClose,
160 this.Label1});
161 this.Name = "frmMain";
162 this.Text = "INI 2 XML";
163 this.Load += new System.EventHandler(this.frmMain_Load);
164 this.ResumeLayout(false);
165
166 }
167 #endregion
168
169 /// <summary>
170 /// The main entry point for the application.
171 /// </summary>
172 [STAThread]
173 static void Main()
174 {
175 Application.Run(new frmMain());
176 }
177
178 private void frmMain_Load(object sender, System.EventArgs e)
179 {
180 }
181
182 private void btnConvert_Click(object sender, System.EventArgs e)
183 {
184 if (INI2XML.Convert( txtIniFileName.Text, txtXMLFileName.Text ))
185 System.Windows.Forms.MessageBox.Show( "Successfully converted \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"", this.Text, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information );
186 else
187 System.Windows.Forms.MessageBox.Show( "Problem converting \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"", this.Text, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation );
188 }
189
190 private void btnClose_Click(object sender, System.EventArgs e)
191 {
192 this.Close();
193 }
194 }
195 }
196
197
198 INI2XML.cs
199
200 using System;
201
202 namespace Loki
203 {
204 using System.Runtime.InteropServices;
205
206 /// <summary>
207 /// WIN32 API Wrapper class
208 /// </summary>
209 public class WIN32Wrapper
210 {
211 /// <summary>
212 /// Get all the section names from an INI file
213 /// </summary>
214 [ DllImport("kernel32.dll", EntryPoint="GetPrivateProfileSectionNamesA") ]
215 public extern static int GetPrivateProfileSectionNames(
216 [MarshalAs(UnmanagedType.LPArray)] byte[] lpReturnedString,
217 int nSize,
218 string lpFileName);
219
220 /// <summary>
221 /// Get all the settings from a section in a INI file
222 /// </summary>
223 [ DllImport("kernel32.dll", EntryPoint="GetPrivateProfileSectionA") ]
224 public extern static int GetPrivateProfileSection(
225 string lpAppName,
226 [MarshalAs(UnmanagedType.LPArray)] byte[] lpReturnedString,
227 int nSize,
228 string lpFileName);
229 }
230
231
232 /// <summary>
233 /// Convert an INI file into an XML file
234 /// </summary>
235 public class INI2XML
236 {
237 /// <summary>
238 ///
239 /// </summary>
240 public INI2XML()
241 {
242 }
243
244 /// <summary>
245 /// Initial size of the buffer used when calling the Win32 API functions
246 /// </summary>
247 const int INITIAL_BUFFER_SIZE = 1024;
248
249 /// <summary>
250 /// Converts an INI file into an XML file.
251 /// Output XML file has the following structure...
252 /// <?xml version="1.0"?>
253 /// <configuration>
254 /// <section name="Main">
255 /// <setting name="Timeout" value="90"/>
256 /// <setting name="Mode" value="Live"/>
257 /// </section>
258 /// </configuration>
259 /// Example:
260 /// if (Loki.INI2XML.Convert( txtIniFileName.Text ))
261 /// System.Console.WriteLine( "Successfully converted \"" + txtIniFileName.Text + "\" to xml" );
262 /// else
263 /// System.Console.WriteLine( "Problem converting \"" + txtIniFileName.Text + "\" to xml" );
264 /// If an exception is raised, it is passed on to the caller.
265 /// </summary>
266 /// <param name="strINIFileName">File name of the INI file to convert</param>
267 /// <returns>True if successfuly, or False if a problem</returns>
268 public static bool Convert( string strINIFileName )
269 {
270 return Convert( strINIFileName, "" );
271 }
272
273 /// <summary>
274 /// Converts an INI file into an XML file.
275 /// Output XML file has the following structure...
276 /// <?xml version="1.0"?>
277 /// <configuration>
278 /// <section name="Main">
279 /// <setting name="Timeout" value="90"/>
280 /// <setting name="Mode" value="Live"/>
281 /// </section>
282 /// </configuration>
283 /// Example:
284 /// if (Loki.INI2XML.Convert( txtIniFileName.Text, txtXMLFileName.Text ))
285 /// System.Console.WriteLine( "Successfully converted \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"" );
286 /// else
287 /// System.Console.WriteLine( "Problem converting \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"" );
288 /// If an exception is raised, it is passed on to the caller.
289 /// </summary>
290 /// <param name="strINIFileName">File name of the INI file to convert</param>
291 /// <param name="strXMLFileName">File name of the XML file that is created</param>
292 /// <returns>True if successfuly, or False if a problem</returns>
293 public static bool Convert( string strINIFileName, string strXMLFileName )
294 {
295 char[] charEquals = {'='};
296 string lpSections;
297 int nSize;
298 int nMaxSize;
299 string strSection;
300 int intSection;
301 int intNameValue;
302 string strName;
303 string strValue;
304 string strNameValue;
305 string lpNameValues;
306 int intPos;
307 byte[] str = new byte[1];
308 System.IO.StreamWriter fileStream;
309
310 if ( strXMLFileName.Length == 0 )
311 {
312 // set the XML's file name based on the INI file name
313 intPos = strINIFileName.LastIndexOf( ".ini" );
314 if ( intPos >= 0 )
315 {
316 strXMLFileName = strINIFileName.Substring( 0, intPos ) + ".xml";
317 }
318 else
319 {
320 strXMLFileName = strINIFileName + ".xml";
321 }
322 }
323
324 // Get all sections names
325 // Making sure allocate enough space for data returned
326 for (nMaxSize = INITIAL_BUFFER_SIZE / 2,
327 nSize = nMaxSize;
328 nSize != 0 && nSize >= (nMaxSize-2);
329 nMaxSize *= 2)
330 {
331 str = new byte[nMaxSize];
332 nSize = WIN32Wrapper.GetPrivateProfileSectionNames( str, nMaxSize, strINIFileName);
333 }
334
335 // convert the byte array into a .NET string
336 lpSections = System.Text.Encoding.ASCII.GetString( str );
337
338 // Create XML File
339 fileStream = System.IO.File.CreateText( strXMLFileName );
340
341 // Write the opening xml
342 fileStream.WriteLine( "<?xml version=\"1.0\"?><configuration>" );
343
344 // Loop through each section
345 char[] charNull = {'\0'};
346 for (intSection = 0,
347 strSection = GetToken(lpSections, charNull, intSection);
348 strSection.Length > 0;
349 strSection = GetToken(lpSections, charNull, ++intSection) )
350 {
351 // Write a Node for the Section
352 fileStream.WriteLine( "<section name=\"" + strSection + "\">" );
353
354 // Get all values in this section, making sure to allocate enough space
355 for (nMaxSize = INITIAL_BUFFER_SIZE,
356 nSize = nMaxSize;
357 nSize != 0 && nSize >= (nMaxSize-2);
358 nMaxSize *= 2)
359 {
360 str = new Byte[nMaxSize];
361 nSize = WIN32Wrapper.GetPrivateProfileSection(strSection, str, nMaxSize, strINIFileName);
362 }
363
364 // convert the byte array into a .NET string
365 lpNameValues = System.Text.Encoding.ASCII.GetString( str );
366
367 // Loop through each Name/Value pair
368 for (intNameValue = 0,
369 strNameValue = GetToken(lpNameValues, charNull, intNameValue);
370 strNameValue.Length > 0;
371 strNameValue = GetToken(lpNameValues, charNull, ++intNameValue) )
372 {
373 // Get the name and value from the entire null separated string of name/value pairs
374 // Also escape out the special characters, (ie. &"<> )
375 strName = XMLEncode( GetToken( strNameValue, charEquals, 0 ) );
376 strValue = XMLEncode( strNameValue.Substring( strName.Length + 1 ) );
377
378 // Write the XML Name/Value Node to the xml file
379 fileStream.WriteLine( "<setting name=\"" + strName + "\" value=\"" + strValue + "\"/>");
380 }
381
382 // Close the section node
383 fileStream.WriteLine( "</section>" );
384 }
385
386 // Thats it
387 fileStream.WriteLine( "</configuration>" );
388 fileStream.Close();
389
390 return true;
391 } // Convert
392
393 /// <summary>
394 /// Encodes special characters that XML has problems with, ie.
395 /// Character Encoded to
396 /// & &
397 /// " "
398 /// < <
399 /// > > intSection = 0
400 /// strSection = GetToken(lpSections, charNull, intSection)
401 /// </summary>
402 /// <param name="strText">Text that needs encoding</param>
403 /// <returns>Encoded text</returns>
404 public static string XMLEncode( string strText)
405 {
406 string strTextRet = strText;
407
408 strTextRet = strTextRet.Replace( "&", "&" );
409 strTextRet = strTextRet.Replace( "\"", """);
410 strTextRet = strTextRet.Replace( "<", "<");
411 strTextRet = strTextRet.Replace( ">", ">");
412
413 return strTextRet;
414 }
415
416 /// <summary>
417 /// Get a token from a delimited string, eg.
418 /// intSection = 0
419 /// strSection = GetToken(lpSections, charNull, intSection)
420 /// </summary>
421 /// <param name="strText">Text that is delimited</param>
422 /// <param name="delimiter">The delimiter, eg. ","</param>
423 /// <param name="intIndex">The index of the token to return, NB. first token is index 0.</param>
424 /// <returns>Returns the nth token from a string.</returns>
425 private static string GetToken( string strText, char[] delimiter, int intIndex )
426 {
427 string strTokenRet = "";
428
429 string[] strTokens = strText.Split( delimiter );
430
431 if ( strTokens.GetUpperBound(0) >= intIndex )
432 strTokenRet = strTokens[intIndex];
433
434 return strTokenRet;
435 } // GetToken
436 } // class INI2XML
437 } // namespace Loki
438
439
440
2
3 using System;
4 using System.Drawing;
5 using System.Collections;
6 using System.ComponentModel;
7 using System.Windows.Forms;
8 using System.Data;
9
10 namespace Loki
11 {
12 /// <summary>
13 /// Summary description for Form1.
14 /// </summary>
15 public class frmMain : System.Windows.Forms.Form
16 {
17 public System.Windows.Forms.Button btnConvert;
18 public System.Windows.Forms.TextBox txtXMLFileName;
19 public System.Windows.Forms.Label Label2;
20 public System.Windows.Forms.TextBox txtIniFileName;
21 public System.Windows.Forms.Button btnClose;
22 public System.Windows.Forms.Label Label1;
23
24 /// <summary>
25 /// Required designer variable.
26 /// </summary>
27 private System.ComponentModel.Container components = null;
28
29 public frmMain()
30 {
31 //
32 // Required for Windows Form Designer support
33 //
34 InitializeComponent();
35 }
36
37 /// <summary>
38 /// Clean up any resources being used.
39 /// </summary>
40 protected override void Dispose( bool disposing )
41 {
42 if( disposing )
43 {
44 if (components != null)
45 {
46 components.Dispose();
47 }
48 }
49 base.Dispose( disposing );
50 }
51
52 #region Windows Form Designer generated code
53 /// <summary>
54 /// Required method for Designer support - do not modify
55 /// the contents of this method with the code editor.
56 /// </summary>
57 private void InitializeComponent()
58 {
59 this.btnConvert = new System.Windows.Forms.Button();
60 this.txtXMLFileName = new System.Windows.Forms.TextBox();
61 this.txtIniFileName = new System.Windows.Forms.TextBox();
62 this.Label1 = new System.Windows.Forms.Label();
63 this.btnClose = new System.Windows.Forms.Button();
64 this.Label2 = new System.Windows.Forms.Label();
65 this.SuspendLayout();
66 //
67 // btnConvert
68 //
69 this.btnConvert.BackColor = System.Drawing.SystemColors.Control;
70 this.btnConvert.Cursor = System.Windows.Forms.Cursors.Default;
71 this.btnConvert.Location = new System.Drawing.Point(160, 96);
72 this.btnConvert.Name = "btnConvert";
73 this.btnConvert.RightToLeft = System.Windows.Forms.RightToLeft.No;
74 this.btnConvert.Size = new System.Drawing.Size(105, 25);
75 this.btnConvert.TabIndex = 4;
76 this.btnConvert.Text = "&Convert";
77 this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click);
78 //
79 // txtXMLFileName
80 //
81 this.txtXMLFileName.AcceptsReturn = true;
82 this.txtXMLFileName.AutoSize = false;
83 this.txtXMLFileName.BackColor = System.Drawing.SystemColors.Window;
84 this.txtXMLFileName.Cursor = System.Windows.Forms.Cursors.IBeam;
85 this.txtXMLFileName.ForeColor = System.Drawing.SystemColors.WindowText;
86 this.txtXMLFileName.Location = new System.Drawing.Point(104, 48);
87 this.txtXMLFileName.MaxLength = 0;
88 this.txtXMLFileName.Name = "txtXMLFileName";
89 this.txtXMLFileName.RightToLeft = System.Windows.Forms.RightToLeft.No;
90 this.txtXMLFileName.Size = new System.Drawing.Size(273, 25);
91 this.txtXMLFileName.TabIndex = 3;
92 this.txtXMLFileName.Text = "";
93 //
94 // txtIniFileName
95 //
96 this.txtIniFileName.AcceptsReturn = true;
97 this.txtIniFileName.AutoSize = false;
98 this.txtIniFileName.BackColor = System.Drawing.SystemColors.Window;
99 this.txtIniFileName.Cursor = System.Windows.Forms.Cursors.IBeam;
100 this.txtIniFileName.ForeColor = System.Drawing.SystemColors.WindowText;
101 this.txtIniFileName.Location = new System.Drawing.Point(104, 16);
102 this.txtIniFileName.MaxLength = 0;
103 this.txtIniFileName.Name = "txtIniFileName";
104 this.txtIniFileName.RightToLeft = System.Windows.Forms.RightToLeft.No;
105 this.txtIniFileName.Size = new System.Drawing.Size(273, 25);
106 this.txtIniFileName.TabIndex = 1;
107 this.txtIniFileName.Text = "E:\\Source\\Loki\\INI2XML\\VB.NET\\projINI2XML.NET\\Sample.ini";
108 //
109 // Label1
110 //
111 this.Label1.AutoSize = true;
112 this.Label1.BackColor = System.Drawing.SystemColors.Control;
113 this.Label1.Cursor = System.Windows.Forms.Cursors.Default;
114 this.Label1.ForeColor = System.Drawing.SystemColors.ControlText;
115 this.Label1.Location = new System.Drawing.Point(16, 24);
116 this.Label1.Name = "Label1";
117 this.Label1.RightToLeft = System.Windows.Forms.RightToLeft.No;
118 this.Label1.Size = new System.Drawing.Size(68, 13);
119 this.Label1.TabIndex = 0;
120 this.Label1.Text = "INI Filename";
121 //
122 // btnClose
123 //
124 this.btnClose.BackColor = System.Drawing.SystemColors.Control;
125 this.btnClose.Cursor = System.Windows.Forms.Cursors.Default;
126 this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
127 this.btnClose.Location = new System.Drawing.Point(272, 96);
128 this.btnClose.Name = "btnClose";
129 this.btnClose.RightToLeft = System.Windows.Forms.RightToLeft.No;
130 this.btnClose.Size = new System.Drawing.Size(105, 25);
131 this.btnClose.TabIndex = 5;
132 this.btnClose.Text = "Close";
133 this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
134 //
135 // Label2
136 //
137 this.Label2.AutoSize = true;
138 this.Label2.BackColor = System.Drawing.SystemColors.Control;
139 this.Label2.Cursor = System.Windows.Forms.Cursors.Default;
140 this.Label2.ForeColor = System.Drawing.SystemColors.ControlText;
141 this.Label2.Location = new System.Drawing.Point(16, 56);
142 this.Label2.Name = "Label2";
143 this.Label2.RightToLeft = System.Windows.Forms.RightToLeft.No;
144 this.Label2.Size = new System.Drawing.Size(77, 13);
145 this.Label2.TabIndex = 2;
146 this.Label2.Text = "XML Filename";
147 //
148 // frmMain
149 //
150 this.AcceptButton = this.btnConvert;
151 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
152 this.CancelButton = this.btnClose;
153 this.ClientSize = new System.Drawing.Size(392, 141);
154 this.Controls.AddRange(new System.Windows.Forms.Control[] {
155 this.btnConvert,
156 this.txtXMLFileName,
157 this.Label2,
158 this.txtIniFileName,
159 this.btnClose,
160 this.Label1});
161 this.Name = "frmMain";
162 this.Text = "INI 2 XML";
163 this.Load += new System.EventHandler(this.frmMain_Load);
164 this.ResumeLayout(false);
165
166 }
167 #endregion
168
169 /// <summary>
170 /// The main entry point for the application.
171 /// </summary>
172 [STAThread]
173 static void Main()
174 {
175 Application.Run(new frmMain());
176 }
177
178 private void frmMain_Load(object sender, System.EventArgs e)
179 {
180 }
181
182 private void btnConvert_Click(object sender, System.EventArgs e)
183 {
184 if (INI2XML.Convert( txtIniFileName.Text, txtXMLFileName.Text ))
185 System.Windows.Forms.MessageBox.Show( "Successfully converted \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"", this.Text, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information );
186 else
187 System.Windows.Forms.MessageBox.Show( "Problem converting \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"", this.Text, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation );
188 }
189
190 private void btnClose_Click(object sender, System.EventArgs e)
191 {
192 this.Close();
193 }
194 }
195 }
196
197
198 INI2XML.cs
199
200 using System;
201
202 namespace Loki
203 {
204 using System.Runtime.InteropServices;
205
206 /// <summary>
207 /// WIN32 API Wrapper class
208 /// </summary>
209 public class WIN32Wrapper
210 {
211 /// <summary>
212 /// Get all the section names from an INI file
213 /// </summary>
214 [ DllImport("kernel32.dll", EntryPoint="GetPrivateProfileSectionNamesA") ]
215 public extern static int GetPrivateProfileSectionNames(
216 [MarshalAs(UnmanagedType.LPArray)] byte[] lpReturnedString,
217 int nSize,
218 string lpFileName);
219
220 /// <summary>
221 /// Get all the settings from a section in a INI file
222 /// </summary>
223 [ DllImport("kernel32.dll", EntryPoint="GetPrivateProfileSectionA") ]
224 public extern static int GetPrivateProfileSection(
225 string lpAppName,
226 [MarshalAs(UnmanagedType.LPArray)] byte[] lpReturnedString,
227 int nSize,
228 string lpFileName);
229 }
230
231
232 /// <summary>
233 /// Convert an INI file into an XML file
234 /// </summary>
235 public class INI2XML
236 {
237 /// <summary>
238 ///
239 /// </summary>
240 public INI2XML()
241 {
242 }
243
244 /// <summary>
245 /// Initial size of the buffer used when calling the Win32 API functions
246 /// </summary>
247 const int INITIAL_BUFFER_SIZE = 1024;
248
249 /// <summary>
250 /// Converts an INI file into an XML file.
251 /// Output XML file has the following structure...
252 /// <?xml version="1.0"?>
253 /// <configuration>
254 /// <section name="Main">
255 /// <setting name="Timeout" value="90"/>
256 /// <setting name="Mode" value="Live"/>
257 /// </section>
258 /// </configuration>
259 /// Example:
260 /// if (Loki.INI2XML.Convert( txtIniFileName.Text ))
261 /// System.Console.WriteLine( "Successfully converted \"" + txtIniFileName.Text + "\" to xml" );
262 /// else
263 /// System.Console.WriteLine( "Problem converting \"" + txtIniFileName.Text + "\" to xml" );
264 /// If an exception is raised, it is passed on to the caller.
265 /// </summary>
266 /// <param name="strINIFileName">File name of the INI file to convert</param>
267 /// <returns>True if successfuly, or False if a problem</returns>
268 public static bool Convert( string strINIFileName )
269 {
270 return Convert( strINIFileName, "" );
271 }
272
273 /// <summary>
274 /// Converts an INI file into an XML file.
275 /// Output XML file has the following structure...
276 /// <?xml version="1.0"?>
277 /// <configuration>
278 /// <section name="Main">
279 /// <setting name="Timeout" value="90"/>
280 /// <setting name="Mode" value="Live"/>
281 /// </section>
282 /// </configuration>
283 /// Example:
284 /// if (Loki.INI2XML.Convert( txtIniFileName.Text, txtXMLFileName.Text ))
285 /// System.Console.WriteLine( "Successfully converted \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"" );
286 /// else
287 /// System.Console.WriteLine( "Problem converting \"" + txtIniFileName.Text + "\" to \"" + txtXMLFileName.Text + "\"" );
288 /// If an exception is raised, it is passed on to the caller.
289 /// </summary>
290 /// <param name="strINIFileName">File name of the INI file to convert</param>
291 /// <param name="strXMLFileName">File name of the XML file that is created</param>
292 /// <returns>True if successfuly, or False if a problem</returns>
293 public static bool Convert( string strINIFileName, string strXMLFileName )
294 {
295 char[] charEquals = {'='};
296 string lpSections;
297 int nSize;
298 int nMaxSize;
299 string strSection;
300 int intSection;
301 int intNameValue;
302 string strName;
303 string strValue;
304 string strNameValue;
305 string lpNameValues;
306 int intPos;
307 byte[] str = new byte[1];
308 System.IO.StreamWriter fileStream;
309
310 if ( strXMLFileName.Length == 0 )
311 {
312 // set the XML's file name based on the INI file name
313 intPos = strINIFileName.LastIndexOf( ".ini" );
314 if ( intPos >= 0 )
315 {
316 strXMLFileName = strINIFileName.Substring( 0, intPos ) + ".xml";
317 }
318 else
319 {
320 strXMLFileName = strINIFileName + ".xml";
321 }
322 }
323
324 // Get all sections names
325 // Making sure allocate enough space for data returned
326 for (nMaxSize = INITIAL_BUFFER_SIZE / 2,
327 nSize = nMaxSize;
328 nSize != 0 && nSize >= (nMaxSize-2);
329 nMaxSize *= 2)
330 {
331 str = new byte[nMaxSize];
332 nSize = WIN32Wrapper.GetPrivateProfileSectionNames( str, nMaxSize, strINIFileName);
333 }
334
335 // convert the byte array into a .NET string
336 lpSections = System.Text.Encoding.ASCII.GetString( str );
337
338 // Create XML File
339 fileStream = System.IO.File.CreateText( strXMLFileName );
340
341 // Write the opening xml
342 fileStream.WriteLine( "<?xml version=\"1.0\"?><configuration>" );
343
344 // Loop through each section
345 char[] charNull = {'\0'};
346 for (intSection = 0,
347 strSection = GetToken(lpSections, charNull, intSection);
348 strSection.Length > 0;
349 strSection = GetToken(lpSections, charNull, ++intSection) )
350 {
351 // Write a Node for the Section
352 fileStream.WriteLine( "<section name=\"" + strSection + "\">" );
353
354 // Get all values in this section, making sure to allocate enough space
355 for (nMaxSize = INITIAL_BUFFER_SIZE,
356 nSize = nMaxSize;
357 nSize != 0 && nSize >= (nMaxSize-2);
358 nMaxSize *= 2)
359 {
360 str = new Byte[nMaxSize];
361 nSize = WIN32Wrapper.GetPrivateProfileSection(strSection, str, nMaxSize, strINIFileName);
362 }
363
364 // convert the byte array into a .NET string
365 lpNameValues = System.Text.Encoding.ASCII.GetString( str );
366
367 // Loop through each Name/Value pair
368 for (intNameValue = 0,
369 strNameValue = GetToken(lpNameValues, charNull, intNameValue);
370 strNameValue.Length > 0;
371 strNameValue = GetToken(lpNameValues, charNull, ++intNameValue) )
372 {
373 // Get the name and value from the entire null separated string of name/value pairs
374 // Also escape out the special characters, (ie. &"<> )
375 strName = XMLEncode( GetToken( strNameValue, charEquals, 0 ) );
376 strValue = XMLEncode( strNameValue.Substring( strName.Length + 1 ) );
377
378 // Write the XML Name/Value Node to the xml file
379 fileStream.WriteLine( "<setting name=\"" + strName + "\" value=\"" + strValue + "\"/>");
380 }
381
382 // Close the section node
383 fileStream.WriteLine( "</section>" );
384 }
385
386 // Thats it
387 fileStream.WriteLine( "</configuration>" );
388 fileStream.Close();
389
390 return true;
391 } // Convert
392
393 /// <summary>
394 /// Encodes special characters that XML has problems with, ie.
395 /// Character Encoded to
396 /// & &
397 /// " "
398 /// < <
399 /// > > intSection = 0
400 /// strSection = GetToken(lpSections, charNull, intSection)
401 /// </summary>
402 /// <param name="strText">Text that needs encoding</param>
403 /// <returns>Encoded text</returns>
404 public static string XMLEncode( string strText)
405 {
406 string strTextRet = strText;
407
408 strTextRet = strTextRet.Replace( "&", "&" );
409 strTextRet = strTextRet.Replace( "\"", """);
410 strTextRet = strTextRet.Replace( "<", "<");
411 strTextRet = strTextRet.Replace( ">", ">");
412
413 return strTextRet;
414 }
415
416 /// <summary>
417 /// Get a token from a delimited string, eg.
418 /// intSection = 0
419 /// strSection = GetToken(lpSections, charNull, intSection)
420 /// </summary>
421 /// <param name="strText">Text that is delimited</param>
422 /// <param name="delimiter">The delimiter, eg. ","</param>
423 /// <param name="intIndex">The index of the token to return, NB. first token is index 0.</param>
424 /// <returns>Returns the nth token from a string.</returns>
425 private static string GetToken( string strText, char[] delimiter, int intIndex )
426 {
427 string strTokenRet = "";
428
429 string[] strTokens = strText.Split( delimiter );
430
431 if ( strTokens.GetUpperBound(0) >= intIndex )
432 strTokenRet = strTokens[intIndex];
433
434 return strTokenRet;
435 } // GetToken
436 } // class INI2XML
437 } // namespace Loki
438
439
440