Try this custom C# code approach
Example of ftp_remotePath content:
Studio 2024.10.12 Windows project
Dependencies:
UiPath.System.Activities.24.10.7
UiPath.FTP.Activities.2.4.0
Import these namespaces in the Studio Imports panel:
System
System.Data
System.Linq
Renci.SshNet
Add a Try Catch activity
Add an Invoke Code for C# with this code:
// Declare DataTable outside the try block for broader access
System.Data.DataTable out_dt = new System.Data.DataTable();
try
{
// Define authentication (using password)
var authMethod = new Renci.SshNet.PasswordAuthenticationMethod(ftp_username, ftp_password);
// Initialize connection info with authentication
var con = new Renci.SshNet.ConnectionInfo(ftp_hostname, ftp_port_number, ftp_username, authMethod);
using (var client = new Renci.SshNet.SftpClient(con))
{
client.Connect();
if (client.IsConnected)
{
var files = client.ListDirectory(ftp_remotePath);
// Define columns for DataTable only once
out_dt.Columns.Add("Name", typeof(string));
out_dt.Columns.Add("FullName", typeof(string));
out_dt.Columns.Add("IsSymbolicLink", typeof(string));
out_dt.Columns.Add("isRegularFile", typeof(string));
out_dt.Columns.Add("Type", typeof(string));
foreach (var file in files)
{
out_dt.Rows.Add(file.Name, file.FullName, file.IsSymbolicLink, file.IsRegularFile, file.IsDirectory ? "Folder" : "File");
}
// Display the DataTable contents (optional)
// Console.WriteLine("Listing Objects in Directory (Folders and Files):");
//foreach (DataRow row in out_dt.Rows)
//{
//Console.WriteLine($"Name: {row["Name"]}, Type: {row["Type"]}");
//}
}
client.Disconnect();
}
ftp_dt_ToUseInWorkflow = out_dt;
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
throw; // Re-throws the caught exception
}
In the Invoked code arguments add these arguments:
Name: ftp_dt_ToUseInWorkflow → Direction: Out → Type: System.Data.DataTable → Value: out_DTResponse
Name: ftp_hostname → Direction: In → Type: System.String → Value: "ftp_hostname"
Name: ftp_username > Direction: In → Type: System.String → Value: "ftp_username"
Name: ftp_port_number > Direction: In → Type: System.Int32 → Value: ftp_port_number
Name: ftp_password → Direction: In → Type: System.String → Value: "ftp_password"
Name: ftp_remotePath → Direction: In → Type: System.String → Value: "/ftp_folder_path"
Example:
Add a For Each activity for out_dtResponse.AsEnumerable()

In the For Each Body add this log message for testing purposes:
"Name: " + currentDataRow("Name").ToString + vbCr + "FullName: " + currentDataRow("FullName").ToString + vbCr + "IsSymbolicLink: " + currentDataRow("IsSymbolicLink").ToString + vbCr + "isRegularFile: " + currentDataRow("isRegularFile").ToString + vbCr + "Type: " + currentDataRow("Type").ToString
Example results: