This is an old revision of the document!

Downloading and Installing WinSCP .NET Assembly

Advertisement

Downloading

WinSCP .NET assembly is available in a package named WinSCP-X.X.X-Automation.zip on WinSCP download page. Follow the .NET assembly/COM library link.

Installing

The package includes the assembly itself (winscpnet.dll) and a required dependency, WinSCP 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 installing the assembly to GAC), make use of the Session.ExecutablePath property to force the assembly to look for the winscp.exe in a different location.

Further steps depend on a development environment/programming languages, that you will use with the assembly:

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 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.

Using from Visual Studio or other Development or Runtime Environment

Note that your runtime or development environment may copy the assembly into an another location. In that case you need to copy winscp.exe into that location too.

Advertisement

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 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 ASP.NET web application, Azure WebJob or Azure Function).

Easier, than setting up the reference manually, is using WinSCP NuGet package.

NuGet Package

WinSCP .NET assembly is available as 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.

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.

Installing to GAC

In special cases, you may need to install the assembly into Global Assembly Cache (GAC), particularly to use it from SSIS.

When you install the assembly to GAC, you need to configure a path to WinSCP executable.

In many cases, instead of using GAC, you can subscribe AppDomain.AssemblyResolve event.

On Development Machine

To install the assembly into GAC on development machine, i.e. the one that has Windows SDK installed, use following command:

gacutil.exe /i WinSCPnet.dll

Windows SDK comes with Microsoft Visual Studio. You can also install it separately.

Use correct gacutil.exe for your version of .NET framework:

  • 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;
  • 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

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;
  • Any other installer system that supports installing to GAC, e.g. Inno Setup;
  • System.EnterpriseServices.Internal.Publish.GacInstall method. PowerShell example:
    Add-Type -AssemblyName "System.EnterpriseServices"
    $publish = New-Object System.EnterpriseServices.Internal.Publish
    $publish.GacInstall("C:\path\WinSCPnet.dll")
    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).1

Advertisement

Registering for COM

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 PowerShell.

%WINDIR%\Microsoft.NET\Framework\<version>\RegAsm.exe WinSCPnet.dll /codebase /tlb

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 applications.2 On 64-bit systems, you should generally register the assembly both for 32-bit (such as old versions of 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:

%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:WinSCPnet64.tlb

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

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 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

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 can find the executable.

Advertisement

Embedding WinSCP Binaries

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.3

Now, before you open a session, extract the winscp.exe from resources to a temporary file using a code like:

// 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);
}

Embedding/Merging Assembly

If you are using a tool like Costura.Fody to embed WinSCPnet.dll into your executable, you will need to set 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.

Advertisement

  1. Check if C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WinSCPnet folder containing the assembly was created.Back
  2. What is obviously available on 64-bit systems only.Back
  3. You cannot use NuGet package in this case, as it does not add winscp.exe visibly to the project, so you cannot change its properties.Back

Last modified: by martin