Chilkat v9.5.0.72 Release Notes

The v9.5.0.71 release notes are available here: Chilkat v9.5.0.71 Release Notes

v9.5.0.72 Release Notes:

  • FTP2 Fixed FTP implicit SSL/TLS uploads for some FTP servers.
  • CkString Fixed: In the Delphi DLL build, the CkString.split* and tokenize* methods caused a crash.
  • Encryption Modification: Encrypting 0 bytes for block cipher algorithms with padding now results in one block of output, rather than 0 bytes.
    (Decrypting the 16-byte block will return the original 0 bytes.) This only applies to block ciphers operating in modes such as ECB, CBC, etc. This does not apply to stream ciphers, or block ciphers operating in a streaming mode.
  • XML Fixed cases where “ ” was getting changed to 
 in round-trip load/save.
  • HTTP The Http.AwsSignatureVersion property default value is changed from 2 to 4. All AWS regions support v4 signatures, whereas S3 regions deployed after January, 2014 do not support V2.
  • PrivateKey Fixed a problem in loading certain (seldom encountered) types of private keys. Specifically, keys using PBES1/RC4.
  • PKCS7 Signature Fixed certain cases where creating PKCS7 signatures embedded the same certificate twice.

C# TreeView to JSON and Back

Here’s a C# class for persisting a TreeView to JSON, and for restoring a TreeView from JSON.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ChilkatRelease
    public class TreeviewPersist

        // Persist the TreeView to a JSON string.
        static public string ToJson(TreeView treeView)
            Chilkat.JsonObject tvJson = new Chilkat.JsonObject();
            Chilkat.JsonArray tvNodes = tvJson.AppendArray("treeViewNodes");

            TreeNodeCollection nodes = treeView.Nodes;
            foreach (TreeNode n in nodes)
                serializeTree(tvNodes, n);

            tvJson.EmitCompact = false;
            return tvJson.Emit();

        // Clears the passed-in treeView and rebuilds from JSON.
        static public void FromJson(string strJson, TreeView treeView)

            Chilkat.JsonObject tvJson = new Chilkat.JsonObject();
            Chilkat.JsonArray tvNodes = tvJson.ArrayOf("treeViewNodes");

            int numNodes = tvNodes.Size;
            for (int i = 0; i < numNodes; i++)
                Chilkat.JsonObject json = tvNodes.ObjectAt(i);

                if (json.IsNullOf("parentName"))
                    TreeNode node = treeView.Nodes.Add(json.StringOf("name"), json.StringOf("text"));
                    restoreNode(node, json);
                    // Assumes unique names (i.e. keys)
                    TreeNode[] foundNodes = treeView.Nodes.Find(json.StringOf("parentName"), true);
                    if (foundNodes.Length > 0)
                        TreeNode node = foundNodes[0].Nodes.Add(json.StringOf("name"), json.StringOf("text"));
                        restoreNode(node, json);


        // Restore the properties of a TreeNode from JSON.
        static private void restoreNode(TreeNode node, Chilkat.JsonObject json)
            node.Tag = json.StringOf("tag");
            node.Text = json.StringOf("text");
            node.ToolTipText = json.StringOf("toolTipText");
            node.Checked = json.BoolOf("checked");

        // Recursive method to add TreeView nodes to the JSON.
        static private void serializeTree(Chilkat.JsonArray tvNodes, TreeNode treeNode)

            Chilkat.JsonObject json = tvNodes.ObjectAt(tvNodes.Size-1);
            json.UpdateString("name", treeNode.Name);

            TreeNode parent = treeNode.Parent;
            if (parent != null)
                json.UpdateString("parentName", treeNode.Parent.Name);

            json.UpdateString("tag", (string)treeNode.Tag);
            json.UpdateString("text", treeNode.Text);
            json.UpdateString("toolTipText", treeNode.ToolTipText);
            json.UpdateBool("checked", treeNode.Checked);

            foreach (TreeNode tn in treeNode.Nodes)



Chilkat v9.5.0.71 Release Notes

The v9.5.0.70 release notes are available here: Chilkat v9.5.0.70 Release Notes

v9.5.0.71 Release Notes:

  • FileAccess Added the GetFileTime method to get the last-modified, created, or last-access file date/time.
  • Email Automatically fixes FROM email addresses to prevent email spoofing as described at
  • FileAcccess If FileSize() returns -1 (failed), then the LastMethodSuccess property was not properly set. (The LastMethodSuccess is a property common to Chilkat classes that is automatically set when any method that returns an integer, string, or object is called.)
  • WebSocket Fixed so that if corrupt data is received (i.e. bytes that do not conform to the WebSocket framing protocol), then the connection is closed as per the WebSocket standard.
  • OAEP Added the OapeMgfHash property to the Email, Crypt2, Mime, and Rsa classes.
  • XmlDSigGen Added support for XML canonicalization WithComments algorithms.
  • StreamConnector/Crypt2 Fixed Crypt2.DecryptStream for cases in .NET when a StreamConnector is used.
  • AuthAws Fixed AWS authentication for Amazon SES.
  • Jwe Fixed problem with RSA-OAEP-256. Also added support for RSA-OAEP-384 and RSA-OAEP-512
  • Rest Added the ConnectTimeoutMs property.
  • MailMan Added the LogMailReceivedFilename property to log a POP3 conversation to a file in real-time.
  • PHP Added thread-safe builds for PHP 7.2 (as opposed to only supporting NTS builds).
  • SFTP Added the XferByteCount property to allow for applications to access the current upload or download transfer byte count for ongoing asynchronous transfers.
  • SSH/SFTP Added the ServerIdentifier property.
  • Csv Added property EnableQuotes such if set to False/0, causes the parser to not treat double-quotes chars as special.
  • C++ Builder Added a build for C++ Builder 10, which includes a build for the 32-bit clang library.
  • Jwe Fixed to internally restrict IV’s to 96 bits as standards dictate.
  • Node.js Added builds for Node.js 9.*.*
  • Dkim Added methods that use BinData. Deprecated methods that use byte arrays or CkByteData.
  • StringBuilder Added methods for punycode.
  • Ruby Added builds for Ruby 2.5.*
  • OpenSSL Decrypt Added feature to be able to decrypt files encrypted using an openssl command such as “openssl enc -e -aes-256-cbc -in hamlet.xml -out hamlet.enc -pass file:./secret.txt”. See
  • CkHashtable Fixed crash bug in the AddFromXmlSb method.
  • Email Added a method named ApplyFixups. (Read more about it in the online reference documentation.)
  • SshKey Added support for the EC key format used by openssl. (No coding changes required, Chilkat automatically recognizes the key format when loading/parsing.)
  • FileAccess Fixed issues with TreeDelete: (1) It returned false when it actually succeeded, and (2) it failed to delete read-only files.
  • SecureString Added the SecureString class to help keep passwords encrypted in memory.
  • Crypt2 Added the DecryptSecureENC and EncryptSecureENC methods.
  • Imap Added the LoginSecure method.
  • MailMan Added the SetPassword method (to set the password using a SecureString rather than just setting the Password property).
  • Ssh, SFtp, SshTunnel Added AuthenticateSecPw and AuthenticateSecPwPk methods.
  • Http Added the SetPassword method so that a password may be set via a SecureString.
  • Rest Added the SetAuthBasicSecure method.
  • SFtp Added the following methods: SymLink,HardLink, ReadLink, and FSync.

Minimizing Time to Send Email

Programmers using Chilkat to send email can do some simple things, and can avoid common mistakes to optimize the time it takes to send an email.

1) A common mistake is when a programmer calls mailman.VerifySmtpConnection and mailman.VerifySmtpLogin prior to actually sending the email. The intent of the Verify methods is for an application to examine connectivity and login success after a call to SendEmail returns a non-success status. The best option is to simply call SendEmail first. If successful, then all is good. If not, then first examine the mailman.SmtpFailReason property. It will provide a general reason for failure, and two of these reasons are ConnectFailed and AuthFailure.

Many mail servers are SLOW in the time it takes to respond to a login. For example, we’ve seen many cases where Office365 takes 3-4 seconds to respond to the AUTH command (i.e. the login). An application wouldn’t want to experience this delay twice for every email sent. This is what happens if VerifySmtpLogin is called prior to each call to SendEmail.

2) When SendEmail completes successfully, Chilkat leaves the authenticated connection with the SMTP server open so that a subsequent call to SendEmail will use the already-established connection. However, if the connection is idle for a long time, a mail server is likely to close the connection. This is no problem for Chilkat because if SendEmail finds the connection closed, it will automatically re-establish and re-authenticate and all is good — except for the time delay in performing the re-connect and re-authenticate, which can be large. Therefore, an application could periodically call mailman.SmtpNoop to prevent the connection from being idle for too long, and thus prevent the mail server from closing the connection. This way, it’s more likely that the next SendEmail will find a valid/authenticated connection.

3) The LastErrorText property is common to most Chilkat objects. A feature of the LastErrorText is that if VerboseLogging is turned on, then the elapsed time (in milliseconds) for each context is shown within LastErrorText. (For cases where a context takes less that 1 milliseconds, the elapsed time is omitted.) Thus an examination of the verbose mailman.LastErrorText can help identify where the time was spent in sending an email. One can identify the time spent in the TLS handshake, in the SMTP authentication, and in the sending of the DATA and waiting for the final SMTP status response.

4) Finally, if you’re using an old version of Chilkat (meaning years old), make sure to update to the latest version. Over the years Chilkat is always improving the internals for performance and memory usage. At this point in time, slowness in sending email is highly likely to be caused by server slowness or other external factors, and not something within Chilkat. (I would venture to say this is also the case for any client-side implementation of SMTP — the slowness is not likely to be caused by the client-side implementation.)

Chilkat v9.5.0.70 Release Notes

The v9.5.0.69 release notes are available here: Chilkat v9.5.0.69 Release Notes

v9.5.0.70 Release Notes:

  • WebSocket Added the WebSocket class.
  • FTP2 The LargeFileMeasures property now applies to uploads. (It originally applied only to FTP downloads.)
  • FTP2 For synchronization uploads, such as for the SyncRemoteTree method, the AutoGetSizeForProgress property now applies. The local directory tree is only scanned to determine the total upload size, which is required for percent-done progress monitoring, if the AutoGetSizeForProgress property is true. There have been cases where the local directory tree is so large, that it takes a long time to recursively scan and the FTP server returns the following error when the uploads finally begin: [421 No-transfer-time exceeded. Closing control connection.]
  • Zip Fixed the ability to create zips using any of PPMD, LZMA, and Bzip2 compression.
  • Crypt2 Added the LastJsonData method.
  • Rest Fixed ServerSentEvent problems with Firebase
  • Zip Fixed the AppendString2 method to not include the utf-8 preamble when the charset argument is “utf-8”.
  • ZipEntry Fixed the ReplaceString and AppendString methods. The charset argument for these method was getting ignored.
  • PKCS7 Digital Signatures (This could apply to Crypt2 or Mime.) In very rare cases, the internal ASN.1 for a part of the PKCS7 signature used something called a “t61” string. Chilkat now handles it correctly.
  • XmlDSigGen Added the IncNamespacePrefix and IncNamespaceUri properties.
  • XmlDSigGen Added a special behavior for the prefixList argument of the AddSameDocRef method. The keyword “_EMPTY_” may be passed to force the generation of an InclusiveNamespaces element with an empty PrefixList under the Transform element. See the online reference documentation for details.
  • XmlDSigGen Added the Behaviors property to account for special needs. See the online reference documentation for details.
  • PreferIpv6 Added internal re-try functionality to cope with various situations for IPv4-only and IPv6-only networks.
  • Tar Fixed bug in AddFile2. See Tar AddFile2 Bug Fix
  • OAuth1 Added the Realm property.
  • IMAP If the date/time string passed to the AppendMimeWithDateStr method used “UTC”, such as in “18-Oct-2017 09:08:21 UTC”, then Chilkat would pass a date/time string without the UTC. This caused the IMAP server (or at least one particular IMAP server) to use it’s local date/time. The IMAP RFC specifies that the timezone part of the date/time string should be in the format +/- 4DIGIT, such as “+0800”. Chilkat now automatically converts the “UTC” (or GMT) to “+0000”.
  • PureBasic The string “data” is a keyword in PureBasic. There has been trouble with the fact that some argument names in the provided .pb files, such as CkJsonObject.pb, contain function arguments named “data”. These have been renamed to “argData” to avoid PureBasic compile errors.
  • Rest Added the AddPathParam and ClearAllPathParams methods.
  • Mac OS X Fixed problem with the AbortCurrent property for CkoFtp2 and other classes.
  • HTTP Fixed problem with using the caching feature (FetchFromCache, UpdateCache, AddCacheRoot, NumCacheLevels, etc.). If the http.AllowGzip property was set to true, and a Gzip response was cached, then a subsequent cache-hit would not return the ungzipped response (as would a normal non-cache-hit response).

Chilkat v9.5.0.69 Release Notes

The v9.5.0.68 release notes are available here: Chilkat v9.5.0.68 Release Notes

v9.5.0.69 Release Notes:

  • XML Digital Signatures Chilkat introduces two new classes for creating and verifying XML Digital Signatures: XmlDSig (for verification) and XmlDSigGen for generating XML signatures. More examples will be available soon.
  • S/MIME The ability to get the digest and encryption algorithms encountered when verifying signatures and decrypting S/MIME. See S/MIME Get Algorithms for a C# example. (The same example is available in all the other programming languages at
  • Rest Added the Rest.ClearAuth method.
  • StringBuilder Fixed a bug in the LastNLines method.
  • General Fixed issues having to do with the XFS Linux filesystem. (Most Linux boxes do not use XFS, and thus the problems were not often encountered.)
  • CkDateTime The DiffSeconds method returned 0 when it should’ve returned a negative number. See DiffSeconds
  • SFTP In rare cases, when aborting a high-speed download, the LastErrorText would become filled with a repeated message “Socket recv aborted by application.”. This was fixed.
  • Crypt2 The GenerateUuid method should now correctly generate a v4 UUID (as opposed to a completely random UUID).
  • SFTP Added a workaround for a glitch in the “SSH-2.0-Connect:Enterprise_UNIX_2.4.04 Build 00” SSH server.
  • Http Added the LastStatusText property.
  • PureBasic Fixed errors in the generated .pb wrappers. For example, in CkJsonObject.pb, the following syntax error occurred when building: “[COMPILER] Line 54: A variable can’t be named the same as a keyword: data.”
  • Socket Added the SendWakeOnLan method.
  • Certificates Chilkat now fully supports certificates that use the RSASSA-PSS signature algorithm.
  • Socket Fixed the BuildHttpGetRequest method.
  • Ssh Fixed: calling the method QuickShell() generates an Access Violation when the LAN connection has been severed.
  • SFTP Fixed (rare) problem such that on some downloads, an unexpected message is received from the server after the download is completed and when closing the handle.
  • IMAP Fixed a rare internal IMAP message parsing error in FetchSingleHeader.
  • ZipEntry Added the IsAesEncrypted and EncryptionKeyLen properties.
  • AWS/S3/Http Fixed problems with pre-signing URLs having to do with 8bit non-us-ascii chars in the filename, or “.” chars in the bucket name.
  • AuthAws Fixed: The CanonicalizedResourceV2 property implementation took the whole string and encoded the entire subresource part by escaping reserved (as defined in rfc2396) characters, but the ‘?’ and ‘&’ characters should not have been escaped.
  • Mime When a message contained 8bit message/rfc822 parts, the GetMime method did not properly emit the MIME. This was fixed.
  • AWS/S3 Fixed: In certain situations, the Content-MD5 header was added twice, which caused the AWS Signature format v2 to fail.
  • Rest The AddMwsSignature method did not compute the signature properly when a query param value contained a “/” char. This was fixed.
  • Ftp2 Fixed a PBSZ issue that occurred for some FTP servers.
  • MailMan Fixed some HTTP proxy issues.
  • Certificates Fixed an issue with automatically locating pre-installed Windows certificates (for encryption) when
    the email address stored within the certificate used uppercase letters.
  • Socket Added the BindAndListenPortRange method.
  • OAuth2 Added the ListenPortRangeEnd property.
  • Ftp2 Fixed the GetCreateDtByName for the following situation. If the value of the ListPattern property changes, then the internal cache of remote file information needed to be automatically cleared so that GetCreateDtByName would not return null and would instead fetch the information from the server.
  • Http Added the PTextSb and PBinaryBd methods.
  • FileAccess Fixed: The GetLastModified method did not work for directories.
  • Zip Fixed the ZipAppendOneFileOrDir method for the case when a UNC path is passed.
  • Imap Fixed the GetMailAttachFilename method for cases where Q/B encoding was used in an IMAP response.

Setup Google Account for Google Drive API Walkthrough

A software developer had trouble getting started using Chilkat with his application for Google Drive. He gave me his login/password to help get him started. This blog post is a recording of the steps I’ve taken to set things up on the Google side to allow an application to access Google Drive files using a Client_ID and Client_Secret.

A Client_ID/Secret implies that the developer will need to create a Project in Google. Once created, we may need to generate keys.

Step 1: Log in to the Google Account and get our Bearings

Ok, I logged into the customer’s Google account. (I notify the customer before doing so, just so he knows exactly when I’m working on it, and I notify the customer when I’m finished.) Often logging in requires the customer to allow it because Google will send a text message or some other notification indicating a login from an unknown device…

OK.. so the login is OK, and I go to Google Drive and see 2 JPG files and a Getting Started PDF that was created by Google. When I run my test application, my goal is to see these 2 JPG files listed..

Step 2: Possibly Create an Project in Google

We may need to create a Project in Google to correspond to our actual application written in some programming language (VB6, C#, C++, Perl, Java, Ruby, …) which uses Chilkat.

I go to The top right portion of the web page looks like this:

Notice the “My Project” dropdown at the top of the web page, just to the left of the “Google APIs” logo. This shows the currently selected project. Google likely automatically added the “My Project”. You may create a new project by clicking on the dropdown and following the links. I’ll use “My Project” for my testing..

Step 3: Enable the Google Drive API

I find that the customer already enabled the Google Drive API. That’s good. If it’s not enabled, then click on the “Enable API” link, find Google Drive, and enable it.

Step 4: Do we have Credentials Setup?

Click on the “Credentials” link in the left rail. I find 2 credentials already created: One listed under “API Keys”, and the other listed under OAuth 2.0 client IDs. Here’s a screenshot. I omitted most of the API key for security. The client ID does not need to be kept secret.

We’ll need an OAuth 2.0 client ID, but it must be the correct type. We won’t be using anything listed under the “API keys”. In this case, the Client ID named “Other client 1” has the type “other”, and is not the type of Client ID we need.

Even though our application may not be a web app, we’ll still need an OAuth client ID for a web application. (Our application could be a desktop app, such as C#, VB6, Delphi, C++, Java, etc., or it could be a script in Perl, Python, PHP, Ruby, VBScript, etc.)

Step 5: Create Credentials of the Correct Type.

Click on the Create Credentials dropdown and choose OAuth client ID.

As shown below, choose “Web application” (even though your app is a desktop app or script), and add an Authorized redirect URIs using “localhost”, such as “http://localhost:55568/”.   The 55568 is a port number.  You may choose any port that is likely not already used on the system.  Choose a port in the ephemeral port range.  Note: The redirect URL must end in a “/”.  Do not use “https”, use “http”.  (This is not a security issue because the callback is from the browser to  your app running on the same system.)

Looking at our credentials again, we can see the Client ID we just created:

Step 6: Get the Client ID and Client Secret.

Click on “Chilkat test 1” to get the Client ID and Client Secret.  These are the strings we’ll need to fetch an OAuth2 access token.  We’ll only need to fetch it once.  The access token can be saved to a file, database, etc. and then used with our API calls, even for the next time we run our application.  In other words, you may persist the access token.

Step 7: Use the Client ID and Client Secret to get an Access Token.

Here’s sample code demonstrating how to do it:

C: Google OAuth2 Access Token
Chilkat2-Python: Google OAuth2 Access Token
C++: Google OAuth2 Access Token
C#: Google OAuth2 Access Token
DataFlex: Google OAuth2 Access Token
Delphi ActiveX: Google OAuth2 Access Token
Delphi DLL: Google OAuth2 Access Token
.NET Core C#: Google OAuth2 Access Token
Excel: Google OAuth2 Access Token
Visual FoxPro: Google OAuth2 Access Token
Java: Google OAuth2 Access Token
Lianja: Google OAuth2 Access Token
MFC: Google OAuth2 Access Token
Mono C#: Google OAuth2 Access Token
Node.js: Google OAuth2 Access Token
Objective-C: Google OAuth2 Access Token
Perl: Google OAuth2 Access Token
PHP ActiveX: Google OAuth2 Access Token
PHP Extension: Google OAuth2 Access Token
PowerBuilder: Google OAuth2 Access Token
PowerShell: Google OAuth2 Access Token
PureBasic: Google OAuth2 Access Token
Python: Google OAuth2 Access Token
Ruby: Google OAuth2 Access Token
Swift: Google OAuth2 Access Token
Tcl: Google OAuth2 Access Token
Unicode C: Google OAuth2 Access Token
Unicode C++: Google OAuth2 Access Token
Visual Basic 6.0: Google OAuth2 Access Token
VB.NET: Google OAuth2 Access Token
VBScript: Google OAuth2 Access Token
Xojo Plugin: Google OAuth2 Access Token

Step 8: Use the Access Token in an API Call

C: List Files in Google Drive
Chilkat2-Python: List Files in Google Drive
C++: List Files in Google Drive
C#: List Files in Google Drive
DataFlex: List Files in Google Drive
Delphi ActiveX: List Files in Google Drive
Delphi DLL: List Files in Google Drive
.NET Core C#: List Files in Google Drive
Excel: List Files in Google Drive
Visual FoxPro: List Files in Google Drive
Java: List Files in Google Drive
Lianja: List Files in Google Drive
MFC: List Files in Google Drive
Mono C#: List Files in Google Drive
Node.js: List Files in Google Drive
Objective-C: List Files in Google Drive
Perl: List Files in Google Drive
PHP ActiveX: List Files in Google Drive
PHP Extension: List Files in Google Drive
PowerBuilder: List Files in Google Drive
PowerShell: List Files in Google Drive
PureBasic: List Files in Google Drive
Python: List Files in Google Drive
Ruby: List Files in Google Drive
Swift: List Files in Google Drive
Tcl: List Files in Google Drive
Unicode C: List Files in Google Drive
Unicode C++: List Files in Google Drive
Visual Basic 6.0: List Files in Google Drive
VB.NET: List Files in Google Drive
VBScript: List Files in Google Drive
Xojo Plugin: List Files in Google Drive



Java to copy byte[] to/from a CkByteArray

The Chilkat online reference documentation for the CkByteData class, concerning the methods for copying Java byte arrays into and out of a CkByteData object, are incorrect.

This is the correct way to do it:

CkByteData byteData = new CkByteData();

// Create a Java byte array with some bytes..
byte[] myData = "Any String you want".getBytes();

// Copy the bytes from the Java byte array into the CkByteData.

// Copy the bytes from the CkByteData to a new Java byte array.
byte[] myData2 = byteData.toByteArray();

Chilkat v9.5.0.68 Release Notes

The v9.5.0.67 release notes are available here:  Chilkat v9.5.0.67 Release Notes

v9.5.0.68 Release Notes:

Version is virtually the same as, but with one important bug fix in the JsonOjbect.UpdateString method that warranted a new release.  Some additional methods were added to JsonObject and Http to help in handling potentially large amounts of data.

  • JsonObject.UpdateString — The passed-in string was not being JSON escaped like it was for JsonObject.AppendString.  This would cause problems for non-usascii chars, or certain special chars that need to be escaped, such as double-quotes, LF’s, CR’s, etc.
  • JsonObject:  Added the following methods:  StringOfSb, BytesOf, UpdateSb, and UpdateBd.  The need for these methods became apparent when writing examples for Microsoft Graph / Outlook.  The purpose of the methods is to access a potentially large amount of data within JSON without needing to pass the data back/forth in arguments or return values.  Passing StringBuilder or BinData object references is far more efficient than passing the actual data.
  • Http:  Added the PostJson3 method.  This is the same as PostJson2, except rather than passing the JSON as a string (which could be a potentially large string), we simply pass the JsonObject reference.

Using Chilkat Mono in a Visual Studio C# Project

The Chilkat Mono assembly can be used in a Visual Studio project (any version of Visual Studio).

(From a programming perspective, using the Chilkat Mono classes is the same as using the Chilkat .NET classes. The Chilkat .NET assemblies (available from Chilkat .NET Downloads are mixed-mode assemblies. The outer-layer is fully managed, and the inner core contains the native C++ implementation. The Chilkat Mono solution is different: The .NET/Mono assembly is 100% managed, and there is a 2nd DLL that contains the native C++ implementation. The 100% managed assembly (internally) calls into the native DLL using P/Invoke.)

Actually.. you don’t even need to build the 100% managed assembly.  You can instead just add the Chilkat *.cs source files to your project directly.  (If you open one of the .cs source files, you’ll see how P/Invoke is used.)

  1. Created a Visual Studio project in C:\MyProject
  2. Downloaded the Chilkat Mono .zip from  and unzipped in C:\MyProject
  3. You now have a directory c:\MyProject\chilkatMono-9.5.0.    Within that directory, I have a chilkatCs directory, and a nativeDll directory.
  4. Add all of the .cs source files from chilkatCs to your Visual Studio C# project.  (Note: If you find an “Accounts.cs” source file, delete it and do not add it.)
  5. You don’t necessarily need to add all of the .cs sources, but you must add whatever is necessary to resolve all references.  For example, if you add MailMan.cs, you’ll certainly need to add Email.cs, and that in turn will require Cert.cs, etc.  A good strategy is to add everything, then delete various things that are likely unreferenced by other things.  For example, you can safely get rid of Csr.cs if not using CSR’s.
  6. Add code to your app.  For example:

    Chilkat.Zip zip = new Chilkat.Zip();

  7. You can try building and running, but it’ll fail because the native DLL won’t be found..
  8. Copy the desired 32-bit or 64-bit native DLL into the same directory where your .exe is created.  For example, copy c:\MyProject\chilkatMono-9.5.0\nativeDll\windows\x64\chilkatMono-9_5_0.dll to c:\MyProject\bin\Debug
  9. Assuming your Visual Studio project is “Any CPU”, and you don’t have a “Prefer 32-bit” checkbox checked (in Project Settings), and that you’re running on a 64-bit system, then the .NET runtime should locate and load the 64-bit chilkatMono-9_5_0.dll, and your program runs fine.