Please wait while loading the page. You need to enable javascript to show the content.

n00b trek
Home
August 6th, 2010 — James

I needed the full name of the local computer which is in a domain. I could not find a straight forward way to get it. I found the following to work. Haven’t failed so far on Windows client and server OS (XP+ and Windows 2003+.)

Dns.GetHostEntry(Environment.MachineName).HostName;
Dns.GetHostEntry("127.0.0.1").HostName;
May 25th, 2010 — James

The code in this post works fine if you compile using Visual Studio .NET 2003 with .NET Framework 1.1.

If you compile the same code in .NET Framework 2.0+ it fails. Something is broken in my opinion.

You will get an error: Min (number) must be less than or equal to max (-1) in a Range object.

The error occurs when you don’t specify the data type of the column. A strongly typed data set will not get this error.

I got this error when loaded up some Excel spreadsheet in to a data set and did some search on a column I knew would have integer values. The rest of the columns contain user data that may contain unexpected type.

I cannot comment on why it is failing when the type is the default string type and only on certain values. I haven’t looked at the framework code yet. May never look at it.

Here is one place where a similar problem is discussed.

Here is a code to reproduce the problem. Program.cs

using System;
using System.Data;

class Program
{
    static void Main(string[] args)
    {
        DataSet ds = GetDSNoType();
        LoadData(ds);
        SearchData(ds);
        ds = GetDSWithType();
        LoadData(ds);
        SearchData(ds);
    }
    static void SearchData(DataSet ds)
    {
        Console.WriteLine("Searching data with type: {0}", ds.Tables[0].Columns[0].DataType);
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            string Query = string.Format("some_number={0}", row["some_number"]);
            try
            {
                DataRow[] rows = ds.Tables[1].Select(Query);
            }
            catch (Exception e)
            {
                Console.WriteLine("Query: {0}", e.Message);
            }
        }
    }
    static DataSet GetDSNoType()
    {
        DataSet ds = new DataSet("NewDataSet");
        ds.Tables.Add("T1");
        ds.Tables["T1"].Columns.Add("some_number");
        ds.Tables.Add("T2");
        ds.Tables["T2"].Columns.Add("some_number");
        return ds;
    }
    static DataSet GetDSWithType()
    {
        DataSet ds = new DataSet("NewDataSet");
        ds.Tables.Add("T1");
        ds.Tables["T1"].Columns.Add("some_number", typeof(int));
        ds.Tables.Add("T2");
        ds.Tables["T2"].Columns.Add("some_number", typeof(int));
        return ds;
    }
    static void LoadData(DataSet ds)
    {
        foreach (int index in T1)
            ds.Tables[0].Rows.Add(new object[] { index });
        foreach (int index in T2)
            ds.Tables[1].Rows.Add(new object[] { index });
    }
    static int[] T1 =
    {
        2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
        70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
        92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
        111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
        129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
        147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
        165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
        183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,
        201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
        219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
        237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
        255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
        273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290,
        291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
        309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326,
        327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
        345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
        363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380,
        381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398,
        399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416,
        417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
        435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452,
        453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470,
        471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488,
        489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506,
        507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524,
        525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
        543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
        561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578,
        579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596,
        597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614,
        615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632,
        633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650,
        651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668,
        669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
        687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704,
        705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722,
        723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740,
        741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758,
        759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776,
        777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794,
        795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812,
        813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830,
        831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848,
        849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866,
        867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884,
        885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902,
        903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920,
        921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939 };
    static int[] T2 =
    {
        77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
        100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
        118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
        136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
        154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
        172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
        190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
        208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225,
        226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
        244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
        262, 263, 264, 265, 266, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
        281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
        299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 312, 313, 314, 315, 316, 317,
        318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
        336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353,
        354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 368, 369, 370, 371, 372,
        373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390,
        391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408,
        409, 410, 411, 412, 413, 414, 415, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427,
        428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445,
        446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
        464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481,
        482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499,
        500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517,
        518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535,
        536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553,
        554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571,
        572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589,
        590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607,
        608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625,
        626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
        644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
        662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679,
        680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697,
        698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715,
        716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733,
        734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751,
        752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769,
        770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787,
        788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805,
        806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823,
        824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841,
        842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859,
        860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877,
        878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895,
        896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913,
        914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931,
        932, 933, 934, 935, 936, 937, 938, 939 };
}
March 30th, 2010 — James

Here is the sample code to read the app settings from the web.config file in an application specific folder. You can use this in ASP.NET applications, WCF services and so on.

using System.Web;
using System.Web.Configuration;
using System.Configuration;

public class SomeClass
{
    public void SomeMethod()
    {
            AppSettingsSection section = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath).AppSettings;
            string mysetting1 = section.Settings["mysetting1"].Value;
            string mysetting2 = section.Settings["mysetting2"].Value;
    }
}
March 13th, 2010 — James

I don’t know where you will use it but here is a code that can convert an integer to say for example, HEX string. I needed a base 32 string converter and wrote this one up. This one is about 4 years old.

public class BaseXString
{
	private int maxStringLength = 16;
	private readonly string BaseCharacters;
	private readonly int BaseCharactersLength;

	public BaseXString(string baseCharacters) {
		// Example of a baseCharacter "0123456789ABCDEF" for HEX.
		this.BaseCharacters = baseCharacters;
		this.BaseCharactersLength = baseCharacters.Length;
	}

	public int MaxStringLength { get { return maxStringLength; } set { maxStringLength=value; } }

	public string ConvertToBaseXString(long NumericValue, int totalWidth, char paddingChar) {
		return ConvertToBaseXString(NumericValue).PadLeft(totalWidth, paddingChar);
	}

	public string ConvertToBaseXString(long NumericValue) {
		StringBuilder sb = new StringBuilder();
		int ModVal;
		long OriginalValue = NumericValue;
		char BaseXDig;
		while (NumericValue >= this.BaseCharactersLength) {
			ModVal       = (int) (NumericValue % this.BaseCharactersLength);
			NumericValue = NumericValue / this.BaseCharactersLength;
			BaseXDig     = BaseCharacters[ModVal];
			sb.Insert(0, BaseXDig);
		}
		BaseXDig = BaseCharacters[(int)NumericValue];
		sb.Insert(0, BaseXDig);
		if (sb.Length > this.MaxStringLength)
			throw new ApplicationException(
                        string.Format("{0} - {1}: Converted string exceeds maximum allowed length of {2}.",
                        OriginalValue, sb.ToString(), this.MaxStringLength));
		return sb.ToString().Trim();
	}
}

zipped source of basexstring.cs

March 13th, 2010 — James

This is a wrapper I created 8 years ago for FTP from WinInet and thought I will share. It was written for .NET Framework 1.1, so your mileage may vary. If you need real production quality FTP, you should get a third party component. But for playing around and for simple projects, this will do.

public class FTP
{
	private int InternetHandle = 0;
	private int ConnectHandle = 0;
	private int Context;
	private bool mBinary = false;
	private string __lastErrorMsg;
	public string LastErrorMsg { get { return this.__lastErrorMsg; } }

	public enum FTP_TRANSFER_TYPE : int
	{
		FTP_TRANSFER_TYPE_UNKNOWN = 0x00000000,
		FTP_TRANSFER_TYPE_ASCII = 0x00000001,
		FTP_TRANSFER_TYPE_BINARY = 0x00000002
	}

	public bool Binary
	{
		get
		{
			return mBinary;
		}
		set
		{
			mBinary = value;
		}
	}

	private void SetLastErrorMessage(int Error)
	{
		if (Error < 12000)
			this.__lastErrorMsg = this.GetWin32ErrorMessage(Error);
		else
			this.__lastErrorMsg = this.GetWinInetErrorMessage(Error);
	}

	[DllImport("KERNEL32.DLL", EntryPoint="GetModuleHandleW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern int GetModuleHandle(string ModuleName);
	[DllImport("KERNEL32.DLL", EntryPoint="FormatMessageW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern int FormatMessage(int Flags, int Handle, int Error, int Language, [In][Out] StringBuilder Buffer, int BufferSize, ref int ArgList);
	private string GetWin32ErrorMessage(int Error)
	{
		StringBuilder outBuffer = new StringBuilder(1024);
		int Handle = GetModuleHandle("kernel32.dll");
		int ArgList = 0;
		FormatMessage(0x00000800, Handle, Error,0, outBuffer, 1023, ref ArgList);
		return outBuffer.ToString();
	}

	[DllImport("wininet.dll", EntryPoint="InternetGetLastResponseInfoW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool InternetGetLastResponseInfo(out int Error, [In][Out] StringBuilder Buffer, ref int BufferLength);
	private string GetWinInetErrorMessage(int Error)
	{
		StringBuilder outBuffer = new StringBuilder(1024);
		if (Error == 12003)
		{
			int BufferLength = 1023;
			InternetGetLastResponseInfo(out Error, outBuffer, ref BufferLength);
		}
		else
		{
			int Handle = GetModuleHandle("wininet.dll");
			int ArgList = 0;
			FormatMessage(0x00000800, Handle, Error,0, outBuffer, 1023, ref ArgList);
		}
		return outBuffer.ToString();
	}

	[DllImport("wininet.dll", EntryPoint="InternetOpenW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern int InternetOpen(string Agent, int AccessType, string ProxyName, string ProxyBypass, int Flags);
	[DllImport("wininet.dll", EntryPoint="InternetConnectW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern int InternetConnect(int InternetHandle, string ServerName, int ServerPort, string Username, string Password, int Service, int Flags, out int Context);
	public bool Open(string ServerName, string UserName, string Password)
	{
		int Error;
		// InternetOpen: Pass a "1" for the 2nd param to indicate to skip the proxy for
		// host name look ups due to some rare timeouts with the proxy/dns lookups.
		if (0 == (InternetHandle = InternetOpen("MyApp", 1, null, null, 0)))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		if (0 == (ConnectHandle = InternetConnect(InternetHandle, ServerName, 21, UserName, Password, 1, 0, out Context)))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			InternetCloseHandle(InternetHandle);
			InternetHandle = 0;
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpSetCurrentDirectoryW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpSetCurrentDirectory(int ConnectHandle, string NewDirectory);
	public bool SetCurrentDirectory(string NewDirectory)
	{
		if (!FtpSetCurrentDirectory(ConnectHandle, NewDirectory))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpCreateDirectoryW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpCreateDirectory(int ConnectHandle, string NewDirectory);
	public bool CreateDirectory(string NewDirectory)
	{
		if (!FtpCreateDirectory(ConnectHandle, NewDirectory))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpRemoveDirectoryW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpRemoveDirectory(int ConnectHandle, string RemoteDirectory);
	public bool RemoveDirectory(string RemoteDirectory)
	{
		if (!FtpRemoveDirectory(ConnectHandle, RemoteDirectory))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpGetCurrentDirectoryW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpGetCurrentDirectory(int ConnectHandle, [In][Out] StringBuilder CurrentDirectory, ref int LenCurrentDirectory);
	public bool GetCurrentDirectory(out string CurrentDirectory)
	{
		StringBuilder CurrentDir = new StringBuilder(260);
		int LenCurrentDirectory = 260;
		if (!FtpGetCurrentDirectory(ConnectHandle, CurrentDir, ref LenCurrentDirectory))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		CurrentDirectory = CurrentDir.ToString();
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpPutFileW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpPutFile(int ConnectHandle, string LocalFile, string RemoteFile, int Flags, ref int Context);
	public bool PutFile(string LocalFile, string RemoteFile)
	{
		int Flags = (int)(mBinary ? FTP_TRANSFER_TYPE.FTP_TRANSFER_TYPE_BINARY : FTP_TRANSFER_TYPE.FTP_TRANSFER_TYPE_ASCII);
		if (!FtpPutFile(ConnectHandle, LocalFile, RemoteFile, Flags, ref Context))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpGetFileW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpGetFile(int ConnectHandle, string RemoteFile, string LocalFile, bool FailOnExisting, int FlagsAndAttributes, int Flags, ref int Context);
	public bool GetFile(string RemoteFile, string LocalFile, bool FailOnExisting)
	{
		if (!FtpGetFile(ConnectHandle, RemoteFile, LocalFile, FailOnExisting, 0, 0, ref Context))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="FtpDeleteFileW", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool FtpDeleteFile(int ConnectHandle, string FileName);
	public bool DeleteFile(string RemoteFile)
	{
		if (!FtpDeleteFile(ConnectHandle, RemoteFile))
		{
			this.SetLastErrorMessage(Marshal.GetLastWin32Error());
			return false;
		}
		return true;
	}

	[DllImport("wininet.dll", EntryPoint="InternetCloseHandle", CharSet=CharSet.Auto, SetLastError=true)]
	private static extern bool InternetCloseHandle(int Handle);
	public void Close()
	{
		if (0 != InternetHandle)
		{
			InternetCloseHandle(InternetHandle);
			InternetHandle = 0;
		}
		if (0 != ConnectHandle)
		{
			InternetCloseHandle(ConnectHandle);
			ConnectHandle = 0;
		}
	}

	~FTP()
	{
		Close();
	}
}

zipped source ftp.cs