Differences
This shows you the differences between the selected revisions of the page.
| 2019-05-21 | 2019-05-21 | ||
| unneeded namespace forgotten by previous edit (martin) | Subscribing AppDomain.AssemblyResolve (martin) | ||
| Line 4: | Line 4: | ||
| First, you need to [[library_install|install the WinSCP .NET assembly]]. | First, you need to [[library_install|install the WinSCP .NET assembly]]. | ||
| - | You also need to [[library_install#gac|install the assembly to the GAC]].((SSIS can only use assemblies installed to GAC.)) | + | You also need to [[library_install#gac|install the assembly to the GAC]] or [[#subscribe|subscribe ''AppDomain.AssemblyResolve'' event]] to allow loading the assembly. |
| ===== Using from SSIS ===== | ===== Using from SSIS ===== | ||
| Line 19: | Line 19: | ||
| ===== Deploying WinSCP .NET Assembly ===== | ===== Deploying WinSCP .NET Assembly ===== | ||
| - | When deploying your SSIS package, WinSCP .NET assembly should be [[library_install#gac|installed to GAC]] to be accessible. | + | If you used GAC when developing your SSIS package, WinSCP .NET assembly needs to be [[library_install#gac|installed to GAC]] even on the target machine. |
| - | + | ||
| - | Alternatively, you can subscribe ''[[dotnet>system.appdomain.assemblyresolve|AppDomain.AssemblyResolve]]'' event in a static constructor handler of the script task class to locate the assembly in an another location. For details, see article [[https://blogs.msdn.microsoft.com/dbrowne/2014/06/25/how-to-load-an-assembly-in-a-ssis-script-task-that-isnt-in-the-gac/|How to load an Assembly in a SSIS script task that isn't in the GAC]]. | + | |
| ===== [[example]] Example C# Script Task Code ===== | ===== [[example]] Example C# Script Task Code ===== | ||
| Line 99: | Line 96: | ||
| </code> | </code> | ||
| + | ===== [[subscribe]] Subscribing AppDomain.AssemblyResolve ===== | ||
| + | |||
| + | If you do not want to [[library_install#gac|install the assembly to the GAC]], you can instead subscribe ''[[dotnet>system.appdomain.assemblyresolve|AppDomain.AssemblyResolve]]'' event in a static constructor handler of the script task class to locate the assembly in an another location. For details, see article [[https://blogs.msdn.microsoft.com/dbrowne/2014/06/25/how-to-load-an-assembly-in-a-ssis-script-task-that-isnt-in-the-gac/|How to load an Assembly in a SSIS script task that isn't in the GAC]]. | ||
| + | |||
| + | <code csharp> | ||
| + | using System; | ||
| + | using Microsoft.SqlServer.Dts.Runtime; | ||
| + | using Microsoft.SqlServer.Dts.Tasks.ScriptTask; | ||
| + | using WinSCP; | ||
| + | |||
| + | namespace ST_5a30686e70c04c5a8a93729fd90b8c79 | ||
| + | { | ||
| + | [SSISScriptTaskEntryPoint] | ||
| + | public partial class ScriptMain : VSTARTScriptObjectModelBase | ||
| + | { | ||
| + | private const string LoadingLog = @"C:\winscp\loading.log"; | ||
| + | private const string AssemblyPath = @"C:\winscp\WinSCPnet.dll"; | ||
| + | |||
| + | static ScriptMain() | ||
| + | { | ||
| + | DebugLoading("Setting up assembly resolve handler"); | ||
| + | AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; | ||
| + | } | ||
| + | |||
| + | private static void DebugLoading(string message) | ||
| + | { | ||
| + | message = DateTime.Now.ToLongTimeString() + ": " + message + Environment.NewLine; | ||
| + | // Uncomment to debug assembly loading issues | ||
| + | // File.AppendAllText(LoadingLog, message); | ||
| + | } | ||
| + | |||
| + | private static Assembly AssemblyResolve(object sender, ResolveEventArgs args) | ||
| + | { | ||
| + | try | ||
| + | { | ||
| + | DebugLoading($"Resolving assembly {args.Name}"); | ||
| + | string name = new AssemblyName(args.Name).Name; | ||
| + | DebugLoading($"Assembly name {name}"); | ||
| + | if (name.Equals("WinSCPnet", StringComparison.InvariantCultureIgnoreCase)) | ||
| + | { | ||
| + | DebugLoading($"Loading {name} from {AssemblyPath}"); | ||
| + | Assembly assembly = Assembly.LoadFile(AssemblyPath); | ||
| + | DebugLoading("Loaded"); | ||
| + | return assembly; | ||
| + | } | ||
| + | DebugLoading("Not WinSCPnet"); | ||
| + | return null; | ||
| + | } | ||
| + | catch (Exception e) | ||
| + | { | ||
| + | DebugLoading($"Exception: {e}"); | ||
| + | throw; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </code> | ||