9

Installed WinSCP .net using nuget installer.

Visual Studio 2013

SSIS BIDS 2012

Project references are correct - pointing to DLL that was installed

Project contains one script which is a stripped down version of the sample code from the winscp site. Fails on the first line which tries to instantiate SessionOptions object. If I remove SessionOptions object it's fine.

registered winscpnet.dll in GAC per instructions.

start script in visual studio ssis debugger, get this:

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

    public void Main()
    {

        SessionOptions sessionOptions = new SessionOptions
        {
            Protocol = Protocol.Sftp,
            // To setup these variables, go to SSIS > Variables.
            // To make them accessible from the script task, in the context menu of the task,
            // choose Edit. On the Script task editor on Script page, select ReadOnlyVariables,
            // and tick the below properties.
            HostName = "",
            UserName = "",
            Password = "",
            SshHostKeyFingerprint = ""
        };

            bool fireAgain = false;

         Dts.Events.FireInformation(0, null,
                        string.Format("Upload of  succeeded"),
                        null, 0, ref fireAgain);



            Dts.TaskResult = (int)DTSExecResult.Success;
    }

Adding screencaps of the flow and process

Heres the package Script details Error when I run it Debug spew

UPDATE: Modified the code as follows...exact same result

        public void Main()
    {
        bool fireAgain = false;

        try
        {
            SessionOptions sessionOptions = new SessionOptions
            {
                Protocol = Protocol.Sftp,
                // To setup these variables, go to SSIS > Variables.
                // To make them accessible from the script task, in the context menu of the task,
                // choose Edit. On the Script task editor on Script page, select ReadOnlyVariables,
                // and tick the below properties.
                HostName = "",
                UserName = "",
                Password = "",
                SshHostKeyFingerprint = ""
            };
        }
        catch (Exception ex)
        {

            Dts.Events.FireInformation(0, null,
                           ex.InnerException.Message,
                           null, 0, ref fireAgain);
        }               

            Dts.TaskResult = (int)DTSExecResult.Success;
    }
Liam
  • 27,717
  • 28
  • 128
  • 190
Shaun Neal
  • 1,183
  • 1
  • 10
  • 12
  • I assume the exception has some text/message and type. You have shared only a callstack with us. – Martin Prikryl Mar 26 '15 at 15:27
  • SSIS pops a message box "DTS Script Task: Runtime Error" Project Name: blah "Exception has been thrown by the target of an invocation", the call stack is in the text area below that - pretty standard stuff and consistent with other SO posts (and posts elsewhere) which note issues with using WinSCP under SSIS – Shaun Neal Mar 26 '15 at 15:50
  • In all posts about "Exception has been thrown by the target of an invocation" I can see information about the actual exception that caused it. – Martin Prikryl Mar 27 '15 at 08:07
  • Updated the question with some screencaps of the process - thanks for looking! – Shaun Neal Mar 27 '15 at 16:48
  • It's probably an inner exception, what shows the root cause. You should catch that. – Martin Prikryl Mar 27 '15 at 17:43
  • Updated with results of catching inner exception - same result – Shaun Neal Mar 27 '15 at 19:53
  • An alternative to consider - I always call WinSCP.com using an Execute Process Task. You can pass an entire script on the command line. This has been a simple and reliable method, obviously as long as it meets the particular requirements of your scenario. – Mike Honey Mar 29 '15 at 23:08
  • What if you modified the object creation to span multiple statements. Yes, I know what you've provided matches http://winscp.net/eng/docs/library#csharp but wonder if a bad value for a parameter is causing the initializer to go belly up and thus, you get no useful error message returned. So, `sessionOptions = new SessionOptions(); sessionOptions.Protocol = Protocol.Sftp;...` – billinkc Mar 30 '15 at 03:27
  • 1
    I see that you have added FireInformation call passing InnerException, but I do not see what message you get from that. Btw, does the code even run? Maybe the exception is thrown when the code is loading (as the loader does resolve the dependencies) – Martin Prikryl Mar 30 '15 at 06:55
  • The fireinformation doesnt get to execute. It does load the script because if I remove the instantiation of the object then the code runs...from the original post:" If I remove SessionOptions object it's fine." I tried this again by putting a fireinformation at the top and removing the new sessionobject call - it ran fine – Shaun Neal Mar 31 '15 at 12:14
  • Unfortunately the script method wont work for us due to some weird file naming issues and a bit of post processing that we want to go based on the file that comes back to us – Shaun Neal Mar 31 '15 at 12:15
  • 1
    Ok so billinkc was on the right track - apparently SshHostKeyFingerprint cannot be an empty string - I was able to create a new empty object and assign zero length strings to all the other parameters except this one. The point of the zero length was to just test if it was working, but apparently this particular parameter cannot be blank. – Shaun Neal Mar 31 '15 at 12:21
  • I am getting the exact same error, but I do not know which DLL (if any) I am using that could be causing this error... – Aaron C Apr 05 '21 at 17:22

3 Answers3

13

When third party DLL is used in SSIS Script Task we need to perform GAC.

Please open Command prompt.

cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools"

Run Following command.

gacutil -i <"Path of WinSCP DLL">

After running the GAC command Scrip task should run as expected. At runtime SSIS is unable to get DLL reference and that is the cause for this error.

Hope this works!!

Michael Z.
  • 1,453
  • 1
  • 15
  • 21
Nicky Thakkar
  • 131
  • 1
  • 3
  • @Nicky..voted up..Thanks after many hours struggle and many google didnt resolve the issue...and finally your steps , for me it is Renci.shnet dll was referenced, to add in gacutil resolved it. – AKS Feb 02 '16 at 10:44
  • I'm facing the same error. I'm looking for this WinSCP.dll, and I don't know where is it. Where can I find it's path ? I'm using SSIS and Visual Studio 2015 – Vincent G Oct 28 '16 at 12:34
  • N.B. the assembly will also need to be signed in order to be added to the GAC. – Robbie Dee Nov 22 '17 at 10:27
  • This is actually mentioned in documentation of [WinSCP .NET assembly installation](https://winscp.net/eng/docs/library_install#gac). – Martin Prikryl Apr 12 '18 at 19:18
  • Yes, it works for me and it should be mark as answer! – Cheung May 10 '18 at 08:20
2

I know this is an old issue but hopefully this helps. Basically what you need is this chunk of code outside of the public void main.

public class example
{
    static ScriptMain()
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }

    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.Name.Contains("WinSCPnet"))
        {
            string path = @"Path to DLL";
            return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "WinSCPnet.dll"));
        }
        return null;
    }
    public void Main()
    { can now use DLL things in here}
}

do add the using WinSCP; and add it to your references of course. Good luck.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Fred Montoya
  • 31
  • 1
  • 5
0

I got this same Exception at C# delegate event invocation, after digging it with try catch block, and with help of stacktrace, I found that there was one exception thrown from one of the event handler methods. after fixing that it started working fine.

Rahul Sonone
  • 2,685
  • 1
  • 27
  • 38