VanDyke Software Forums

VanDyke Software Forums (
-   Scripting (
-   -   How to connect in C# via vralib to work just like the sfxcl.exe command line works (

tomfromokaloosa 03-02-2012 08:45 AM

How to connect in C# via vralib to work just like the sfxcl.exe command line works
Summary: SFXCL.EXE command line works, but C# code calling the client pack does not. What more is needed to get this retrieval to work? Does SFXCL.EXE figure out proxy information that the vralib.Connection object doesnít do automatically?

Iíve got a remote server to which Iím connecting using the following batch file (names and passwords changed). This runs successfully from a scheduled task using local machine credentials (MY_MACHINE_NAME\localusername). The retrieval crosses some firewalls and traverses domain boundaries along the way, but I have in no way configured sfxcl.exe for firewalls as far as I can recall. The batch file ONLY contains the following line.

sfxcl.exe /noprompt /move sftp://username:passwordBetterThanThis@Server.IP.Address.Here//server/path/* d:\MyLocalPath2\sftp\

The above command line works.

After installing the ClientPack, the following C# code executes and fails on the line above the comment. The debug file contents follow the sourcecode. I've changed the username, password and numbered IP address in this code sample.

vralib.License lic = new vralib.License();
vralib.Connection conn = new vralib.Connection();
vralib.FileTransferObject fto = new vralib.FileTransferObject();


string connectionString = "sftp://username:passwordBetterThanThis@Server.IP.Address.Here";
conn.DebugLevel = 99;
conn.DebugLogFile = @"D:\MyLocalPath1\logfilename.txt";

fto.SourcePath = "//server/path/*
fto.DestinationPath = @"D:\MyLocalPath2\sftp\";

Iíve run this service with the same credentials that sfxcl.exe is using in a Windows Service and I get the following results. The last line of code that executes is the Connect() call. I've tried running the service under the local machine identity that works from the command line and under a domain identity.

3/1/2012 9:17:12 PM,13672,6,[LOCAL] : SSH2Core version (init timing: 178 milliseconds)
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : Connecting to Server.IP.Address.Here...
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : Changing state from STATE_NOT_CONNECTED to STATE_EXPECT_KEX_INIT
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : RECV: TCP/IP close
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : RECV: OnRead(dwStatus=0x00000000)
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : RECV: CloseTransport(rmp=0x00000000)
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : Changing state from STATE_EXPECT_KEX_INIT to STATE_CLOSED
3/1/2012 9:17:12 PM,13672,6,[LOCAL] : Connected for 0 seconds, 13 bytes sent, 0 bytes received

I'I ran the installer of VanDyke Client pack on a Windows Server 2003 machine.

jdev 03-02-2012 01:44 PM

Hi Tom,

The VRALib Connection object's Connect() method does not operate the same way as the SFXCL command line parser does.

The VRALib's Connection object provided a Connect() call for which the first parameter is only a hostname. If the Connection object's Hostname, Username, and Password properties have all been set before hand, you simply call Connect() with an empty string as the first parameter and false as the second parameter.

In your specific case, there's no such host named "sftp://username:passwordBetterThanThis@Server.IP.Address.Here", which explains why the VRALib Connection object's Connect() method is failing.

I'm including sample code of a C# console app that exemplifies how to accomplish a download operation similar to what you're trying.

Does this example show you how to properly call Connect() after setting the properties for Hostname, Username, Password, etc.?


using System;

namespace VRALibDownloadExample
    class Program
        static void Main(string[] args)
            // For evaluation of VRALib, this code is needed; it does not cause any problems
            // for license/registered VRALib installations, so it can be left in place even
            // after you license VRALib:
            var objLicense = new vralib.License();
            string strEvalLeft = objLicense.AcceptEvaluationLicense();
            if (strEvalLeft.Contains(@"days remaining"))

            // Create a VRAlib Connection object we'll use to control
            // the process of connecting via SSH to the remote system
            vralib.Connection objConn = new vralib.Connection();

            // Enable debug logging for assisting troubleshooting efforts
            objConn.DebugLogFile = @"C:\##vralib-Download-Dbg-Log.txt";
            objConn.DebugLevel = 5;
            objConn.Hostname = @"";
            objConn.Port = 22;
            objConn.Username = @"user";

            // For public/private key authentication, use this (obviously, you'll
            // need to create two variables -- PrivateKeyPath, which contains the full
            // path to the private/public key file; and PrivateKeyPassphrase, which
            // contains the passphrase used to unlock/decrypt the private key for use.
            // Consult the VRALib documenation or more information.
            // objConn.SetPrivateKeyFile(PrivateKeyPath, PrivateKeyPassphrase);

            // Otherwise, just use plain old password auth
            objConn.Password = @"p4$$w0rd";

            // Now Connect to the remote system.  Wrap this in a try/catch block to
            // handle any connection failures "gracefully":
            Console.WriteLine("Connecting to " + objConn.Hostname + ":" + objConn.Port + "...");
                // When the Connection object has all the necessary connection info
                // already set in the form of properties (e.g. objConn.Hostname,
                // objConn.Username, objConn.Password, etc.), all that is needed is to call
                // Connect with an empty string as the first param, and 'false' as the second
                // param (StartAllForwards is a setting that doesn't apply to file transfer
                // connections).  See the VRALib help documentation .chm file for additional
                // details about the Connection object's Connect() method.
                objConn.Connect("", true);
            catch (System.Runtime.InteropServices.COMException objException)
                Console.WriteLine("Failed to connect:\r\n" + objException.ToString());
                Console.WriteLine("Press any key to continue.");
                System.Environment.ExitCode = objException.ErrorCode;
                "Connected and authenticated to " + objConn.Hostname +
                " (" + objConn.RemoteIdentString + ")");

            // Get a reference to a file system object for the remote host
            vralib.IFileSystemObject objRemoteFS = objConn.FileSystemObject;

            // Download remote files (*.txt) to a local folder (C:\Temp\Incoming\)
            string strSrc = "*.txt";
            string strDst = @"C:\Temp\Incoming\";
            Console.WriteLine(@"Downloading '" + strSrc + "' from " +
                objConn.Hostname + " to '" + strDst + "'");
                objRemoteFS.Get(strSrc, strDst);
            catch (System.Runtime.InteropServices.COMException objException)
                Console.WriteLine("Transfer failed:\r\n" + objException.ToString());
                Console.WriteLine("Press any key to continue.");
                System.Environment.ExitCode = objException.ErrorCode;
            catch (System.IO.FileNotFoundException objException)
                Console.WriteLine("Transfer failed:\r\n" + objException.ToString());
                Console.WriteLine("Press any key to continue.");
                System.Environment.ExitCode = 2;
            catch (Exception objException)
                Console.WriteLine("Transfer failed:\r\n" + objException.ToString());
                Console.WriteLine("Press any key to continue.");
                System.Environment.ExitCode = -9999999;

            Console.WriteLine("Transfer succeeded.\r\n\r\nPress any key to contine.");

tomfromokaloosa 03-05-2012 01:57 PM

Failing on VRALib Connect() from C# in a Windows Service
Thank you for your help.

I've also used the following code, except that the address, username, and password have been changed here. The results follow the code, with the actual IP address removed from the log.
conn.DebugLevel = 99;
conn.DebugLogFile = @"D:\logs\SFTPvralib.txt";
conn.Hostname = ""; //actual address instead of this
conn.Port = 22;
conn.Username = "tom"; //actual user instead of this
conn.Password = "betterPassword"; //actual password instead of this

Log Results:
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : SSH2Core version (init timing: 172 milliseconds)
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : Connecting to MY_IP_ADDRESS ...
012 8:18:51 PM,7308,1,[LOCAL] : Changing state from STATE_NOT_CONNECTED to STATE_EXPECT_KEX_INIT
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : RECV: TCP/IP close
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : RECV: OnRead(dwStatus=0x00000000)
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : RECV: CloseTransport(rmp=0x00000000)
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : Changing state from STATE_EXPECT_KEX_INIT to STATE_CLOSED
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : Connected for 0 seconds, 0 bytes sent, 0 bytes received
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : RECV: OnWrite(dwStatus=0x00002746)
3/5/2012 8:18:51 PM,7308,1,[LOCAL] : RECV: CloseTransport(rmp=0xe104000a)

I copied, pasted, and edited the connection object properties from the sfxcl.exe command line parameter that's actually used, so I'm sure that I am using the right credentials. I'm guessing that the response I'm getting is from a firewall in between. Is it possible that sfxcl.exe somehow leverages my certificate store on my server to authenticate to firewalls/proxy servers in between, but the .NET class does not? Is there something else I could be overlooking here?

Note that both the service that has this code in it and sfxcl.exe have been configured to use local machine credentials to keep things as close to identical configuration as possible.

This code gets a clean compile, I've installed the VanDyke Client Pack using the installer, and I'm building my application as a .NET 4.0 windows service.


jdev 03-06-2012 12:08 PM

The log information indicates that the VRALib connection is not able to reach the target machine with an initial TCP/IP connection (the connection is closing even before the server's SSH Ident string shows up, so authentication isn't even a factor yet).
  • Check firewall/proxy rules on the client side to ensure that your .NET exe (the one that's using VRALib) is allowed to make outgoing TCP connections.
  • If by chance you're connecting with your VRALib app from a machine that's different from the machine on which SFXCL is running, you might also consider that something (a firewall rule or connection filter) on the remote side may be disallowing the initial connection if it's coming from a different IP address than expected.
  • If SFXCL is running on the same machine successfully where the VRALib app is running unsuccessfully, then you might check still for a personal firewall that blocks all apps that are not specifically and explicitly allowed to make outgoing connections.
  • Something else that comes to mind is that if SFXCL is using the 'sftp://user:pass@host' URL command line construct, it's getting configuration settings (such as Proxy/Firewall settings) from the "Default" session as defined in the SecureFX application. VRALib is a separate, distinct entity, and does not know about any SecureFX configuration settings. If you have SecureFX's "Default" session configured to connect through a proxy/firewall, you'll need to try and duplicate the same proxy connection configuration in VRALib by setting the appropriate Firewall_________ properties (FirewallHostname, FirewallPort, FirewallType, FirewallUsername (if needed), and FirewallPassword(if needed)) of the VRALib Connection object in your code before you call Connect().
  • One other thing. You're setting DebugLevel = 99, which is excessive. DebugLevel values greater than 9 will expose passwords in the log file, which you may not want to do unless you're trying to debug packet-level data; additional details aren't logged beyond a value of 15 or so, depending on the version you're using. Choosing a debug level of 1 is sufficient to troubleshoot most connection problems.

For example:

            objConn.DebugLevel = 1;
            objConn.Hostname = @"";
            objConn.Port = 22;
            objConn.FirewallHostname = @"";
            objConn.FirewallPort = 1080;
            objConn.FirewallType = @"socks5";
            objConn.Username = @"user";


All times are GMT -6. The time now is 07:35 PM.