Search code examples
c#azure-functionssftpwinscpwinscp-net

WinSCP .NET assembly fails with "The winscp.exe executable was not found" in Session.Open in C# Azure function


First I generated a simple console application to see if the generated by WinSCP works fine - and this was the case

Now I try to write an Azure function using WinSCP - in the same way - the same parameters - and I get an exception on Session.Open (SessionLocalException):

[Error] Executed 'WriteFile' (Failed, Id=68e2ef30-c2fb-4f5e-8444-93634a2728bb, Duration=256ms) The winscp.exe executable was not found at location of the assembly WinSCPnet (D:\home\site\wwwroot\bin), nor the entry assembly Microsoft.Azure.WebJobs.Script.WebHost (D:\Program Files (x86)\SiteExtensions\Functions\3.2.0\32bit), nor in an installation path. You may use Session.ExecutablePath property to explicitly set path to winscp.exe.

The winscp.exe file is not in D:\home\site\wwwroot\bin but in D:\home\site\wwwroot. And as I'm publishing via Visual studio it is read only so I cannot just copy the file on the right location.

How can update my zip deployment so that the file gets in the right place?

My code :

public static async Task<IActionResult> WriteFile(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req)
{
    SessionOptions sessionOptions = new SessionOptions
    {
        Protocol = Protocol.Sftp,
        HostName = "xxx",
        UserName = "xxx",
        Password = "xxx",
        SshHostKeyFingerprint = "xxx",
    };
    using (Session session = new Session())
    {
        try
        {
            session.Open(sessionOptions);
        }
        catch (SessionLocalException)
        {
            content = JsonConvert.SerializeObject(new { success = false, exception = "SessionLocalException", condition = "Error communicating with winscp.com. See the exception documentation for details." });
            return (ActionResult)new OkObjectResult($"{content}");
        }

Exception documentation for details does not help very much Could anybody help me?


In a first time I wrote directly in Azure portal some functions to process SFTP related activities - I was new to Azure Functions but I found a way to get it handled

Now I try to write these functions in Visual Studio 2019 to publish to Azure functions

The problem is that in the C# code when I try to open a session it fails.


Solution

  • This exact problem is documented in WinSCP guide to transfers in Microsoft Azure Function:

    The only problem you will face is, that for some reason, when publishing the project to an Azure storage, winscp.exe dependency is stored to the root folder of the function, instead of the bin subfolder along with other binaries (particularly the WinSCPnet.dll).

    To overcome that, you need to use Session.ExecutablePath to point to the actual location of winscp.exe. You can use ExecutionContext.FunctionAppDirectory to refer to the root folder of the function. To get an instance of the ExecutionContext, add new parameter to the signature of your entry method (usually Run).

    [FunctionName("Function1")]
    public static void Run(
        [TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log, ExecutionContext context)
    {
        // ...
        session.ExecutablePath = Path.Combine(context.FunctionAppDirectory, "winscp.exe");
    }
    

    (for full code, see the guide)


    After all, the exception message suggests the same:

    You may use Session.ExecutablePath property to explicitly set path to winscp.exe.