Okay, I've accomplished what I originally set out to do. I'm going to boil my code down as much as possible just to the C++/MFC lines of code that are germain to the problem. The problem is to programmatically put a file from your computer to an FTP site with Visual Studio C++/MFC code, and then read it back to the same place from which it originally came. Just to make this as clean as possible I'm going to have minimal comments. You can look up the various classes and member functions on MSDN.
This is just an example. For the example, we'll use the following:
Server name: "ftp.pctalk.info"
User name: "frankparis"
Password: "@Junk7"
Internet port: 21
I found that the hardest part of this whole exercise was figuring out what the above four parameters should be. Well, the password and Internet port are fairly straightforward. But it took a lot of experimenting to get the Server name and User name right. Maybe if you understand FTP better than I do all that will be obvious to you.
I tried to format the code that follows the same way it looks in Visual Studio but the "code" BBCodes butcher beyond belief what I input so you just have to bear with it. The "code" BBCodes are basically worthless. Rest assured it is well-formatted with proper indentation in the original.
- Code: Select all
CInternetSession internetSession(_T("AnyIdentifier")); // it doesn't matter what "AnyIdentifier" is
CFtpConnection* pConnect = NULL;
try
{
pConnect = internetSession.GetFtpConnection(_T("ftp.pctalk.info"), _T("frankparis"), _T("@Junk7"), 21);
}
catch (CInternetException* pEx)
{
TCHAR sz[1024];
pEx->GetErrorMessage(sz, 1024);
CString strTitle(_T("FTP Failure"));
CString strTrace;
strTrace.Format(_T("%s: %s\n"), strTitle, sz);
TRACE(strTrace);
pEx->Delete();
}
// If the connection is open, do stuff, then close it.
if (pConnect != NULL)
{
TRACE(_T("FTP Success\n"));
if (pConnect->SetCurrentDirectory(_T("AnyFolderName")))
{
TRACE(_T("FTP Success: Set current directory to \"AnyFolderName\"\n"));
CTime currentTime(CTime::GetCurrentTime());
CString strGmtTime = currentTime.FormatGmt(_T("%Y.%m.%d %H.%M.%S"));
CString strLocalLogFilePath;
// AppDataFolder() gets the fully qualified path where you want to store application data; could be anywhere
strLocalLogFilePath.Format(_T("%s\\%s.txt"), AppDataFolder(), strGmtTime);
CStdioFile localFile(strLocalLogFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
CString strLogLine;
TCHAR strComputerName[1000], strUserName[1000];
DWORD lComputer(1000);
DWORD lName(1000);
::GetComputerName(strComputerName, &lComputer);
::GetUserName(strUserName, &lName);
strLogLine.Format(_T("ComputerName=\"%s\"\nUserName=\"%s\"\nLogID=%d\n"), strComputerName, strUserName, 1);
localFile.WriteString(strLogLine);
localFile.Close();
CString strRemoteLogFileName;
strRemoteLogFileName.Format(_T("%s.txt"), strGmtTime);
// FTP_TRANSFER_TYPE_BINARY so that the newline characters in the formatting aren't lost
// when they're transferred to the FTP site
if (pConnect->PutFile(strLocalLogFilePath, strRemoteLogFileName, FTP_TRANSFER_TYPE_BINARY))
{
CString strLogSuccessMsg;
strLogSuccessMsg.Format(_T("FTP Success: Put log file, \"%s\"\n"), strRemoteLogFileName);
TRACE(strLogSuccessMsg);
}
else
{
TRACE(_T("FTP Failure: Failed to put a log file.\n"));
}
::DeleteFile(strLocalLogFilePath);
// delete the original file so we don't get confused by the results of the next line which gets it back to the same location
pConnect->GetFile(strRemoteLogFileName, strLocalLogFilePath, FTP_TRANSFER_TYPE_BINARY);
}
else
{
TRACE(_T("FTP Failure: Failed to set current directory\n"));
}
// Close FTP connection
pConnect->Close();
delete pConnect;
}