Click here to Skip to main content
15,895,256 members
Articles / Desktop Programming / MFC

Using FTP with .NET including sending server commands

Rate me:
Please Sign up or sign in to vote.
4.56/5 (14 votes)
19 May 20044 min read 135.6K   951   57  
How to send and receive files, enumerate directories and subdirectories remotely on demand, send server commands through FTP control port.
/////////////////////////////////////////////////////////////////////////////////////////////////
//
//  Project:   FTP_Wrap.dll
//  Date:      10/14/2003
//  Revision:  1.0
//
//  This .dll provides a wrapper for the MFC FTP class, CFtpConnection.  This wrapper
//  is used from C# via .NET interoperability.  This wrapper is necessary because the 
//  .NET FCL does not provide FTP classes.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

// FTP_Wrap.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "FTP_Wrap.h"

namespace FTP_Wrap
{
	// 1 = is directory
	// 0 = not a directory
	// -1 = error
	int FTP_Wrapper::IsDirectory(int mode, int FTPPort, System::String* pServerURL, System::String* pUserName, System::String* pPassword, System::String* pRemoteDirNm, System::String*& pErrorMsg)
	{
		int retCode = 0;
		CString ServerURL(pServerURL);
		CString UserName(pUserName);
		CString Password(pPassword);
		CString RemoteDirName(pRemoteDirNm);
		CInternetSession iSess(_T("FTP_Wrap.dll"));
		CFtpConnection* pFtpConn = NULL;
		try
		{
			pFtpConn = iSess.GetFtpConnection(ServerURL, UserName, Password, FTPPort);
			BOOL bSwap = pFtpConn->SetCurrentDirectory(RemoteDirName);
			if (bSwap)
				retCode = 1;
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			retCode = -1;
		}
		
		return retCode;
		
		
	}
	
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  Function: SendFTPFile(System::String* pServerURL, System::String* pUserName, System::String* pPassword, 
	//						  System::String* pLocalFilePathNm, System::String* pRemoteFilePathNm,
	//						  System::String*& pErrorMsg))
	//
	//  Parameters:      pServerURL        --  host name or ip of destination FTP server
	//                   pUserName         --  user name for FTP server.  Leave blank ("") for anonymous.
	//                   pPassword         --  user password for FTP server.  Leave blank ("") for anonymous.
	//                   pLocalFilePathNm  --  Full path name to file to send (i.e. "c:\\files\\file.send").  
	//                                         This path must be relative to whichever box has loaded this .dll.
	//                   pRemoteFilePathNm --  Full path name used to write the file on the FTP server.  
	//                                         To upload to the FTP servers main directory, just pass the file name
	//                                         (i.e. "file.send")
	//                   pErrorMsg         --  Receives information detailing any error conditions that
	//                                         occur (i.e. invalid password) during the send attempt.
	//
	//  Returns:         true if the file was successfully sent.  false if not (and pErrorMsg is populated).
	//
	////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//true = file sent, false file not sent
	bool FTP_Wrapper::SendFTPFile(int mode, int FTPPort, System::String* pServerURL, System::String* pUserName, System::String* pPassword, System::String* pLocalFilePathNm, System::String* pRemoteFilePathNm, System::String*& pErrorMsg)
	{
		CString ServerURL(pServerURL);
		CString UserName(pUserName);
		CString Password(pPassword);
		CString LocalFilePathNm(pLocalFilePathNm);
		CString RemoteFilePathNm(pRemoteFilePathNm);
		
		//First be sure the local file path name is valid:	
		if (!CFileFind().FindFile(LocalFilePathNm))
		{	
			System::Text::StringBuilder * pSb = new System::Text::StringBuilder();
			pSb->Append("The specified file, ");
			pSb->Append(pLocalFilePathNm);
			pSb->Append(", was not found.");			
			pErrorMsg = new System::String(pSb->ToString()->ToCharArray());	
			return false;
		}	
	
		CInternetSession iSess(_T("SEDC_FTP_Wrap.dll"));
		CFtpConnection* pFtpConn = NULL;
		try
		{
			pFtpConn = iSess.GetFtpConnection(ServerURL, UserName, Password, FTPPort);
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}
	
		BOOL bOk = TRUE;
		try
		{
			DWORD xferFlags = 0;
			if (mode == FTP_Wrapper::TransferMode_ASCII)
				xferFlags = FTP_TRANSFER_TYPE_ASCII;
			else
				xferFlags = FTP_TRANSFER_TYPE_BINARY;
			
			bOk = pFtpConn->PutFile( (LPCTSTR) LocalFilePathNm, (LPCTSTR)RemoteFilePathNm, xferFlags );
			if (!bOk)
			{
				pErrorMsg = new System::String("Unable to transfer file");
			}
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}
	
		return (bOk)? true : false;
	}
	
	
	
	
	
	
	
	bool FTP_Wrapper::SendFTPFileToHP3000(int RecSize, int fileType, bool isProg, int discSpace, int mode, int FTPPort, System::String* pServerURL, System::String* pUserName, System::String* pPassword, System::String* pLocalFilePathNm, System::String* pRemoteFilePathNm, System::String*& pErrorMsg)
	{
		System::Text::StringBuilder* pSb = new System::Text::StringBuilder(pRemoteFilePathNm);
		
		
		//Record Size:
		pSb->Append(_T(";REC=-"));
		pSb->Append(RecSize.ToString());
		
		//Skip the blocking factor:
		pSb->Append(_T(",,"));
		
		//File Type (fixed, variable, binary)
		if (fileType == 0) //Fixed
			pSb->Append(_T("F,"));
		else if (fileType == 1) //Variable
			pSb->Append(_T("V,"));
		else //Binary
			pSb->Append(_T("B,"));
			
		//File encoding (ASCII or binary)
		if (mode == 0) // ASCII
			pSb->Append(_T("ASCII;"));
		else           // binary
			pSb->Append(_T("BINARY;"));
			
			
		//File code if specified
		if (isProg)
		{
			pSb->Append(_T("CODE="));
			pSb->Append(_T("NMPRG"));
			pSb->Append(_T(";"));
		}
		
		//Disc space # of records if specified
		if (discSpace != 0)
		{
			pSb->Append(_T("DISC="));
			pSb->Append(discSpace.ToString());
		}
		
		
		
		return FTP_Wrapper::SendFTPFile(mode, FTPPort, pServerURL, pUserName, pPassword, pLocalFilePathNm, pSb->ToString(), pErrorMsg);
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  Function: GetFTPFile(System::String* pServerURL, System::String* pUserName, System::String* pPassword, 
	//                       System::String* pLocalFilePathNm, System::String* pRemoteFilePathNm, 
	//                       System::String*& pErrorMsg)
	//
	//  Parameters:      pServerURL        --  host name or ip of destination FTP server
	//                   pUserName         --  user name for FTP server.  Leave blank ("") for anonymous.
	//                   pPassword         --  user password for FTP server.  Leave blank ("") for anonymous.
	//                   pLocalFilePathNm  --  Full path name to file to Get (i.e. "c:\\files\\file.get").  
	//                                         This path must be relative to whichever box has loaded this .dll.
	//                   pRemoteFilePathNm --  Full path name used to get the file from the FTP server.  
	//                                         To download from the FTP servers main directory, just pass the file name
	//                                         (i.e. "file.get")
	//                   pErrorMsg         --  Receives information detailing any error conditions that
	//                                         occur (i.e. invalid password) during the send attempt.
	//
	//  Returns:         true if the file was successfully received.  false if not (and pErrorMsg is populated).
	//
	////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//true file gotten, false file not gotten
	bool FTP_Wrapper::GetFTPFile(int mode, int FTPPort, System::String* pServerURL, System::String* pUserName, System::String* pPassword, System::String* pLocalFilePathNm, System::String* pRemoteFilePathNm, System::String*& pErrorMsg)
	{
		CString ServerURL(pServerURL);
		CString UserName(pUserName);
		CString Password(pPassword);
		CString LocalFilePathNm(pLocalFilePathNm);
		CString RemoteFilePathNm(pRemoteFilePathNm);
		CInternetSession iSess(_T("SEDC_FTP_Wrap.dll"));
		CFtpConnection* pFtpConn = NULL;
		try
		{
			pFtpConn = iSess.GetFtpConnection(ServerURL, UserName, Password, FTPPort);
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}
	
		//Be sure the remote file exists:
		// use a file find object to enumerate files
		BOOL bFound = FALSE;
		try
		{
			CFtpFileFind finder(pFtpConn);

			// start looping
			bFound = finder.FindFile(RemoteFilePathNm);
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}
	
		if (!bFound)
		{
			TCHAR ErrMsg[255];
			swprintf(ErrMsg, _T("The specified remote file, %s, was not found."), RemoteFilePathNm);
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}
	
		BOOL bOk = TRUE;
		try
		{
			DWORD xferFlags = 0;
			if (mode == FTP_Wrapper::TransferMode_ASCII)
				xferFlags = FTP_TRANSFER_TYPE_ASCII;
			else
				xferFlags = FTP_TRANSFER_TYPE_BINARY;
			
			bOk = pFtpConn->GetFile((LPCTSTR)RemoteFilePathNm, (LPCTSTR) LocalFilePathNm, FALSE, FILE_ATTRIBUTE_NORMAL, xferFlags);
			if (!bOk)
			{
				pErrorMsg = new System::String("Unable to transfer file");
			}
		}
		catch (CInternetException* pe)
		{
			TCHAR ErrMsg[255];
			pe->GetErrorMessage(ErrMsg, 255);
			pe->Delete();
			pErrorMsg = new System::String(ErrMsg);	
			return false;
		}	
		return (bOk)? true : false;
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Chief Technology Officer
United States United States
Working to keep a technology company up to date. Wondering when Microsoft will hire a fresh, innovative guy to run the company.

Comments and Discussions