Search code examples
vbawinapiunicodeftpwininet

WinAPI FTPGetFile Conversion From ANSI to Unicode


Premise: Copying files from Linux to Windows over FTP using WinInet FtpGetFile.

Objective: The files originate as ANSI and are needed in Unicode.

Progress: The only issue I am having is that I need LF characters from the original file to be CRLF characters in the destination file.
I have tried:

Public Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileW" (ByVal hFTP As Long, ByVal sRemoteFile As String, ByVal sNewFile As String, ByVal bFailIfExists As Boolean, ByVal lFlagsAndAttributes As Long, ByVal lFlags As Long, ByVal lContext As Long) As Boolean
Public Sub test(hConn as Long, strSrcPath as String, strDestPath as String)
  'All code works other than the file not converting to having CR chars
  ftpGetFile(hConn, StrConv(strSrcPath, vbUnicode), StrConv(strDestPath, vbUnicode), True, 0, 0, 0)
End Sub
  • (FAILS to convert) using the Unicode version of the FtpGetFile method (Alias FtpGetFileW), passing the arguments using StrConv(<string>, vbUnicode). The files show up with only LF chars at the end of the lines.
  • (WORKS, manually) copying files manually using WinSCP. It automatically makes the output files Unicode but I can't find the method/settings associated with this. I cannot use the WinSCP.dll at my work as I cannot register it.
  • (WORKS, slowly) using a work-around. using the either version of the FtpGetFile. Opening file, reading to variable, closing file and then opening file for write, writing Replace(variable,Chr(10),Chr(13)&Chr(10)). Also, files appear to ~double in size.

How do I get a file using the WinAPI functions and have it convert in one shot (if possible)?

Related articles:
Unicode turns ANSI after FTP transfer
Writing ANSI string to Unicode file over FTP

Source Info:
How to Create FTP Components CodeGuru
MSDN for WinInet


Solution

  • The following appears to be working near instantaneously. If anyone has any better suggestions on how to automate this (preferably without this work-around or to make my work-around better) please provide them. Otherwise, I'll probably be choosing this as the answer in a few days. ftpReadFile is a custom function that uses InternetReadFile and spits out the entire file as a string.

    Public Function ftpGetFileToUnicode(hConn As Long, strFromPath As String, strDestPath As String) As Boolean
      Dim hFile As Long
      Dim objFS As New FileSystemObject, objFile As TextStream
    
      If Not objFS.FileExists(strDestPath) Then
          Set objFile = objFS.CreateTextFile(strDestPath, ForWriting)
          objFile.Write Replace(ftpReadFile(hConn, strFromPath), Chr(10), Chr(13) & Chr(10))
          objFile.Close
    
          If objFS.GetFile(strDestPath).Size > 0 Then
              ftpGetFileToUnicode = True
              Exit Function
          End If
      End If
    
      ftpGetFileToUnicode = False
    End Function
    

    Note: Creates a 0 byte file if the file doesn't exist. Can easily be changed to not do that.