Question

I'm having a problem with my FtpFindFirstFile function on my C# project. Basically this function is just to search the specified directory for a file that I mention in my program, but an error appears right before the function is finish executing, here's the screenshot of the error:

---------------START CODE------------------

[System.Runtime.InteropServices.DllImport("wininet.dll", EntryPoint = "InternetOpen", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr InternetOpen(
              string lpszAgent, int dwAccessType, string lpszProxyName,
              string lpszProxyBypass, int dwFlags);
[System.Runtime.InteropServices.DllImport("wininet.dll", EntryPoint = "InternetConnect", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] 
extern public static IntPtr  /*IntPtr*/ InternetConnect(
         IntPtr hInternet, string lpszServerName, int nServerPort,
         string lpszUsername, string lpszPassword, int dwService,
         int dwFlags, int dwContext);

    [System.Runtime.InteropServices.DllImport("wininet.dll", EntryPoint = "FtpFindFirstFile", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    extern public static IntPtr FtpFindFirstFile(
        IntPtr hConnect, string searchFile, out WIN32_FIND_DATA findFileData,
        int flags, IntPtr context); 

    #region WIN32_Structure

    public struct WIN32_FIND_DATA
    {
        public int dwFileAttributes;
        public int nFileSizeHigh;
        public int nFileSizeLow;
        public int dwReserved0;
        public int dwReserved1;
        public string cFileName; 
        public string cAlternateFileName;
    }
    #endregion

    public void PerformFTP(string HostIP, string logUsrName, string LogPwd, string SendType, string DefaultDir, string fileExtension)
    {
        #region Declaration
        WIN32_FIND_DATA win32 = new WIN32_FIND_DATA();
        bool pRoceed;
        #endregion
        pRoceed = true;

        /*  Initialize Internet Connection */
        IntPtr hInternet = InternetOpen("browser", INTERNET_OPEN_TYPE_DIRECT, null, null, 0);
        //IntPtr hInternet = InternetOpen("browser", 1, null, null, 0);

        if (hInternet == IntPtr.Zero)
        {
            MessageBox.Show(hInternet.ToString(), "");
            MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString()); 
        }

        /*  Initialize FTP Connection  */
        IntPtr hFTPhandle = InternetConnect(hInternet, HostIP, INTERNET_DEFAULT_FTP_PORT, logUsrName, LogPwd, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
        //IntPtr hFTPhandle = InternetConnect(hInternet, "203.177.252.123", 21, "bomoracle", "bomoracle", 1, 0, 0);

        /*  To check if the FTP connection succeeded */
        if (hFTPhandle == IntPtr.Zero)
        {
            pRoceed = false;
            MessageBox.Show(hFTPhandle.ToString(), "");
            MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString());
            return;
        }

        //IntPtr hFind = FtpFindFirstFile(hFTPhandle, "*.DAT" /*+ fileExtension*/ , out win32, 0, IntPtr.Zero);

        IntPtr hFind = FtpFindFirstFile(hFTPhandle, "*.DAT"  , out win32, 0, IntPtr.Zero); **//THIS IS WHERE THE ERROR APPEARS**

        if (hFind == IntPtr.Zero)
        {
            if (System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString() == "RROR_NO_MORE_FILES") 
            {
                MessageBox.Show("NO MORE .BOM FILES","EMPTY");
            }
            MessageBox.Show("SEARCHING IN THE DIRECTORY FAILED! ", "EMPTY");
        }

    }

---------------END CODE------------------

Here's the error message, it appears right before executing the if-else condition:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

I don't know what's causing the error, I was just searching the directory, I haven't done any get or put command on that ftp process. Hope you can help! Thanks!

Était-ce utile?

La solution

I cann't answer your specific question but I strongly feel there is already a managed solution. Remember that you only need to fallback to interop when the framework has no implementation that suits your needs.

var request = (FtpWebRequest)WebRequest.Create("ftp://example.com/");
request.Credentials= new NetworkCredential("username", "password");
// List files
request.Method = WebRequestMethods.Ftp.ListDirectory;

var resp = (FtpWebResponse) request.GetResponse();
var stream = resp.GetResponseStream();
var readStream = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8);

// handle the incoming stream, store in a List, print, find etc
var files = new List<String>();
if (readStream != null)
{
    while(!readStream.EndOfStream)
    {
      files.Add(readStream.ReadLine());
    }
} 
// showe them
foreach(var file in files)
{
   Console.WriteLine(file);
}
// find one
var fileToFind = "Public";
var foundFile = files.Find( f => f == fileToFind);
Console.WriteLine("found file {0}:", foundFile);
// show status
Console.WriteLine("List status: {0}",resp.StatusDescription); 

In this snippet I used:
FtpWebResponse
FtpWebRequest
WebRequestMethods.Ftp
List.Find
StreamReader

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top