Differences
This shows you the differences between the selected revisions of the page.
library_install 2015-02-18 | library_install 2023-09-28 (current) | ||
Line 1: | Line 1: | ||
====== Downloading and Installing WinSCP .NET Assembly ====== | ====== Downloading and Installing WinSCP .NET Assembly ====== | ||
- | ===== Downloading ===== | + | ===== [[downloading]] Downloading ===== |
- | [[library|WinSCP .NET assembly]] is available in a package named ''winscpXXXautomation.zip'' on [[&download|WinSCP download page]]. Follow the //%%.NET assembly/COM library%%// link. | + | [[library|WinSCP .NET assembly]] is available in a package named ''WinSCP-X.X.X-Automation.zip'' on [[&downloads#additional|WinSCP download page]]. Follow the //%%.NET assembly/COM library%%// link. |
- | ===== Installing ===== | + | ===== [[installing]] Installing ===== |
The package includes the assembly itself (''winscpnet.dll'') and a required dependency, WinSCP [[executables|executable]] ''winscp.exe''. | The package includes the assembly itself (''winscpnet.dll'') and a required dependency, WinSCP [[executables|executable]] ''winscp.exe''. | ||
- | The binaries interact with each other and must be kept in the same folder for the assembly to work. In rare situations this is not possible (e.g. when [[#gac|installing the assembly to GAC]]), make use of ''[[library_session#properties|Session.ExecutablePath]]'' property to force the assembly to look for the ''winscp.exe'' in a different location. | + | The binaries interact with each other and must be kept in the same folder for the assembly to work. In rare situations this is not possible (e.g. when [[#gac|installing the assembly to GAC]]), make use of the ''[[library_session#executablepath|Session.ExecutablePath]]'' property to force the assembly to look for the ''winscp.exe'' in a different location. |
- | //Note that in earlier versions, the executable ''winscp.exe'' was not included in the package and had to be downloaded separately.// &recent | + | The version of ''WinSCPnet.dll'' in the root of the package is .NET Framework ==build== of the assembly. If your project targets .NET (Core) or if you use [[library_powershell#powershell|PowerShell (Core) 6/7]], you have to use .NET Standard build of the assembly, which is located in the ''netstandard2.0'' subfolder. The .NET Standard build has some minor limitations and cannot be used with COM. |
+ | |||
+ | Further steps depend on a development environment/programming languages, that you will use with the assembly: | ||
+ | |||
+ | * PowerShell: No additional installations steps are needed. Read about [[library_powershell|using WinSCP .NET assembly from PowerShell]]. | ||
+ | * Visual Studio (C#, VB.NET): For development, you better use the [[#nuget|NugGet package]], instead of installing the assembly manually. The NuGet package will even care for configuring your project to deploy the assembly. | ||
+ | ··* [[library_vb|VBA]], [[library_com_wsh|VBScript, JScript]], [[library_perl|Perl]]: You need to [[#registering|register the assembly for COM]]. | ||
+ | * SSIS: Read about [[library_ssis#using|using WinSCP .NET assembly from SSIS]]. | ||
==== [[vs]] Using from Visual Studio or other Development or Runtime Environment ==== | ==== [[vs]] Using from Visual Studio or other Development or Runtime Environment ==== | ||
Line 17: | Line 24: | ||
E.g. If you reference WinSCP assembly from your project in Microsoft Visual Studio, it copies the assembly during build into the project //Output path// (e.g. ''<your_project_path>/obj/Debug''). Similar case is when you [[#gac|install the assembly into Global Assembly Cache (GAC)]]. | E.g. If you reference WinSCP assembly from your project in Microsoft Visual Studio, it copies the assembly during build into the project //Output path// (e.g. ''<your_project_path>/obj/Debug''). Similar case is when you [[#gac|install the assembly into Global Assembly Cache (GAC)]]. | ||
- | You may want to add ''winscp.exe'' to your Visual Studio project, to have it copied to the //Output path// automatically (by setting file property //Copy to Output Directory// to //Copy if newer//). The //Build Action// should be automatically set to //Content//, what means that the file will be included when deploying your application (e.g. an [[guide_microsoft_azure_webjob_sftp#consoleapp|Azure WebJob application]]). | + | You may want to add ''winscp.exe'' to your Visual Studio project, to have it copied to the //Output path// automatically (by setting file property //Copy to Output Directory// to //Copy if newer//). The //Build Action// should be automatically set to //Content//, what means that the file will be included when deploying your application (e.g. an ASP.NET web application, [[guide_microsoft_azure_webjob_sftp#consoleapp|Azure WebJob]] or [[guide_microsoft_azure_function_sftp|Azure Function]]). |
+ | |||
+ | Easier, than setting up the reference manually, is using [[#nuget|WinSCP NuGet package]]. | ||
==== [[nuget]] NuGet Package ==== | ==== [[nuget]] NuGet Package ==== | ||
- | WinSCP .NET assembly in available as [[https://www.nuget.org/packages/WinSCP/|NuGet package with the same name]]. | + | WinSCP .NET assembly is available as [[https://www.nuget.org/packages/WinSCP/|NuGet package with the same name]]. |
- | The NuGet package includes the assembly itself and the required WinSCP executable. When installed, it adds the assembly as reference to your project and sets up WinSCP executable to be copied to project output directory, so that it can be found on run-time, as described [[#vs|above]]. | + | The NuGet package includes the assembly itself and the required WinSCP executable. When installed, it adds the assembly as reference to your project and sets up WinSCP executable to be copied to project output directory, so that it can be found on run-time. |
No other setup is needed, so you can start coding straight away after installation. | No other setup is needed, so you can start coding straight away after installation. | ||
+ | |||
+ | The NuGet package supports both //Packages.config// and //PackageReference in project file// package management formats. | ||
===== [[gac]] Installing to GAC ===== | ===== [[gac]] Installing to GAC ===== | ||
Line 30: | Line 41: | ||
When you install the assembly to %%GAC%%, you need to [[#installing|configure a path to WinSCP executable]]. | When you install the assembly to %%GAC%%, you need to [[#installing|configure a path to WinSCP executable]]. | ||
+ | |||
+ | In many cases, instead of using GAC, you can [[library_ssis#subscribe|subscribe ''AppDomain.AssemblyResolve'' event]]. | ||
==== On Development Machine ==== | ==== On Development Machine ==== | ||
- | To install the assembly into %%GAC%% on development machine, i.e. the one that has [[http://msdn.microsoft.com/en-us/library/ms717422.aspx|Windows SDK]] installed, use following command: | + | To install the assembly into %%GAC%% on development machine, i.e. the one that has [[https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/|Windows SDK]] installed, use following command: |
<code> | <code> | ||
Line 41: | Line 54: | ||
Use correct ''gacutil.exe'' for your version of .NET framework: | Use correct ''gacutil.exe'' for your version of .NET framework: | ||
- | * For .NET framework 4.0, use ''gacutil'' from Windows SDK 7.1 (or 7.0): ''C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1\bin\gacutil.exe''; &winpath &win32 &win64 | + | * For .NET framework 4.0 or newer, use ''gacutil'' from Windows SDK 7.1 (or newer): \\ ''C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1\bin\gacutil.exe''; &winpath &win32 &win64 |
- | * For .NET framework 3.5, use ''gacutil'' from Windows SDK 6.0: ''C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe'' | + | * For .NET framework 3.5, use ''gacutil'' from Windows SDK 6.0: \\ ''C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe'' |
- | ==== On Production or User's Machine ==== | + | ==== [[production]] On Production or User's Machine ==== |
To install the assembly into %%GAC%% on production or user's machine, you may install the assembly into %%GAC%% using: | To install the assembly into %%GAC%% on production or user's machine, you may install the assembly into %%GAC%% using: | ||
* Windows Installer, by creating ''.msi'' package; | * Windows Installer, by creating ''.msi'' package; | ||
* Any other installer system that supports installing to %%GAC%%, e.g. [[&url(innosetup)|Inno Setup]]; | * Any other installer system that supports installing to %%GAC%%, e.g. [[&url(innosetup)|Inno Setup]]; | ||
- | * [[msdn>System.EnterpriseServices.Internal.Publish.GacInstall]] method. PowerShell example: | + | * [[dotnet>System.EnterpriseServices.Internal.Publish.GacInstall|''System.EnterpriseServices.Internal.Publish.GacInstall'' method]]. PowerShell example: \\ <code powershell> |
- | + | ||
- | <code powershell> | + | |
Add-Type -AssemblyName "System.EnterpriseServices" | Add-Type -AssemblyName "System.EnterpriseServices" | ||
$publish = New-Object System.EnterpriseServices.Internal.Publish | $publish = New-Object System.EnterpriseServices.Internal.Publish | ||
- | $publish.GacInstall("WinSCPnet.dll") | + | $publish.GacInstall("C:\path\WinSCPnet.dll") |
- | </code> | + | </code> An absolute path to the DLL needs to be specified and Administrator privileges are required. Otherwise the above method will fail (and the only indication of the failure is sent to Windows Event log).((Check if ''C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WinSCPnet'' &winpath folder containing the assembly was created.)) |
===== [[registering]] Registering for COM ===== | ===== [[registering]] Registering for COM ===== | ||
- | WinSCP .NET assembly exposes its full interface to COM. As a COM library, it needs to be registered before use. If you are going to use the COM interface, register the assembly using((You do not need to register the assembly, if you are going to use it directly as a .NET assembly)): | + | WinSCP .NET assembly exposes majority of its interface to COM. As a %%COM%% library, it needs to be registered before use. If you are going to use the %%COM%% interface, register the assembly using command below. You do **not** need to register the assembly, if you are going to use it directly as a .NET assembly, e.g. from C#, VB.NET or [[library_powershell|PowerShell]]. |
<code> | <code> | ||
%WINDIR%\Microsoft.NET\Framework\<version>\RegAsm.exe WinSCPnet.dll /codebase /tlb | %WINDIR%\Microsoft.NET\Framework\<version>\RegAsm.exe WinSCPnet.dll /codebase /tlb | ||
</code> | </code> | ||
- | Where the ''%WINDIR%'' is path to your Windows installation, what is typically ''C:\Windows'' or ''C:\WINNT''. Note that you can keep ''%WINDIR%'' as this environment variable should be set on your system to point to the Windows folder. The ''Framework'' needs to be replaced by ''Framework64'' to register the assembly for use from 64-bit &win64 applications((What is obviously available on 64-bit systems only)). On 64-bit system, you should generally register the assembly both for 32-bit and 64-bit application. The ''<version>'' is version of .NET framework to register the assembly with. It is recommended to use the latest available, what currently is ''v4.0.30319''. You may however use any framework version from 2.0 (''v2.0.50727'') up. Note that framework 3.0 and 3.5 do not ship with ''RegAsm.exe''. For these versions use ''RegAsm.exe'' from 2.0. | + | In the command above, the ''%WINDIR%'' is path to your Windows installation, what is typically ''C:\Windows'' or ''C:\WINNT''. Note that you can keep ''%WINDIR%'' as this environment variable should be set on your system to point to the Windows folder. The ''Framework'' needs to be replaced by ''Framework64'' to register the assembly for use from 64-bit &win64 applications.((What is obviously available on 64-bit systems only.)) On 64-bit systems, you should generally register the assembly both for 32-bit (such as old versions of [[library_vb|Microsoft Excel]]) and 64-bit applications. The ''<version>'' is version of .NET framework to register the assembly with. It is recommended to use the latest available, what currently is ''v4.0.30319''. You may however use any framework version from 2.0 (''v2.0.50727'') up. Note that framework 3.0 and 3.5 do not ship with ''RegAsm.exe''. For these versions use ''RegAsm.exe'' from 2.0. |
Typical registration commands for .NET 4.0 on 64-bit system would be: | Typical registration commands for .NET 4.0 on 64-bit system would be: | ||
<code> | <code> | ||
- | %WINDIR%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb | + | %WINDIR%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet32.tlb |
- | %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb | + | %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet64.tlb |
</code> | </code> | ||
The above examples assume that ''WinSCPnet.dll'' is in current working directory. Otherwise you need to specify an absolute path to the ''.dll''. | The above examples assume that ''WinSCPnet.dll'' is in current working directory. Otherwise you need to specify an absolute path to the ''.dll''. | ||
- | ==== Side-by-Side Registration ==== | + | ==== [[side-by-side]] Side-by-Side Registration ==== |
If you register multiple versions of the WinSCP .NET assembly, the .NET framework will always use the latest version registered. | If you register multiple versions of the WinSCP .NET assembly, the .NET framework will always use the latest version registered. | ||
If you want to use different version (i.e. downgrade), you need to unregister all newer versions of the assembly and re-register the version you want to use. | If you want to use different version (i.e. downgrade), you need to unregister all newer versions of the assembly and re-register the version you want to use. | ||
- | If you happen to remove the newest registered assembly, without unregistering it first, you will not be able to instantiate classes from the assembly, no matter that you have older versions of the assembly registered too. You need to download the version you have removed again and unregister it. Exact physical location of the assembly, when unregistering, does not need to match the original location of the removed assembly (as long as the versions match). | + | If you happen to remove the newest registered assembly, without unregistering it first, you will not be able to instantiate classes from the assembly, no matter that you have older versions of the assembly registered too. You need to download the version, you have removed, again and unregister it. Exact physical location of the assembly, when unregistering, does not need to match the original location of the removed assembly (as long as the versions match). |
+ | |||
+ | You can use ''/comregistration'' command-line switch of WinSCP [[executables]] to list (and optionally unregister) all registered versions of the assembly (without having the assembly files). | ||
+ | |||
+ | ===== [[deploying]] Deploying ===== | ||
+ | When deploying the assembly, make sure that WinSCP executable (''winscp.exe'') is deployed along with the assembly on the target system and that WinSCP assembly [[#installing|can find the executable]]. | ||
+ | |||
+ | ===== [[embed]] Embedding WinSCP Binaries ===== | ||
+ | |||
+ | ==== [[resource]] Embedding WinSCP Executable as Resource ==== | ||
+ | |||
+ | If you want to avoid having the ''winscp.exe'' as a separate file (e.g. when whole your project is a single ''.exe'' file and you do not want to have any dependency), you can embed the ''winscp.exe'' as a resource to your own executable. | ||
+ | |||
+ | Add the ''winscp.exe'' to your Visual Studio project. Change file property //Build Action// to the //Embedded Resource//.((You cannot use [[#nuget|NuGet package]] in this case, as it does not add ''winscp.exe'' visibly to the project, so you cannot change its properties.)) | ||
+ | |||
+ | Now, before you open a session, extract the ''winscp.exe'' from resources to a temporary file using a code like: | ||
+ | |||
+ | <code csharp> | ||
+ | // Generate random, yet meaningful name of the temporary file | ||
+ | string tempName = Path.GetTempFileName(); | ||
+ | string executableName = "WinSCP." + Path.ChangeExtension(Path.GetFileName(tempName), "exe"); | ||
+ | string executablePath = Path.Combine(Path.GetDirectoryName(tempName), executableName); | ||
+ | File.Delete(tempName); | ||
+ | |||
+ | // Extract the resource to the temporary file | ||
+ | Assembly executingAssembly = Assembly.GetExecutingAssembly(); | ||
+ | string resName = executingAssembly.GetName().Name + "." + "WinSCP.exe"; | ||
+ | |||
+ | using (Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resName)) | ||
+ | using (Stream file = File.Create(executablePath)) | ||
+ | { | ||
+ | resource.CopyTo(file); | ||
+ | } | ||
+ | |||
+ | try | ||
+ | { | ||
+ | using (Session session = new Session()) | ||
+ | { | ||
+ | // Use the temporarily extracted executable | ||
+ | session.ExecutablePath = executablePath; | ||
+ | |||
+ | // Connect | ||
+ | session.Open(sessionOptions); | ||
+ | |||
+ | // Your code | ||
+ | } | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | // Clean up | ||
+ | File.Delete(executablePath); | ||
+ | } | ||
+ | </code> | ||
- | ===== Deploying ===== | + | ==== [[merge]] Embedding/Merging Assembly ==== |
- | When deploying the assembly, make sure that WinSCP executable (''winscp.exe'') is installed along with the assembly on the target system and that WinSCP assembly [[#installing|can find the executable]]. | + | |
+ | If you are using a tool like [[https://github.com/Fody/Costura|Costura.Fody]] to embed ''WinSCPnet.dll'' into your executable, you will need to set [[library_session#disableversioncheck|''Session.DisableVersionCheck'']]. The WinSCP .NET library code will be merged into the executable assembly and would compare the executable version instead its (lost) version against WinSCP executable version. |