代码
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( " \ "" , " & quot; " );
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( " \ "" , " & quot; " );
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