COM Interop with CLient and Server

3

Hello, I have a DLL to encrypt data. I need to use the Component Object Model (COM) Interop to be able to communicate two applications and both traffic the encrypted data through this DLL. Searching, I found integration examples like integrate with Microsoft Office but not with another application.

As requested, follow the example I found on the Microsoft website (and in DevMedia courses)

using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}


var bankAccounts = new List<Account> 
{
new Account 
{
    ID = 345,
    Balance = 541.27
},
new Account 
{
    ID = 123,
    Balance = -127.44
}
};


void DisplayInExcel(IEnumerable<Account> accounts,
       Action<Account, Excel.Range> DisplayFunc)
{
var excelApp = this.Application;
// Add a new Excel workbook.
excelApp.Workbooks.Add();
excelApp.Visible = true;
excelApp.Range["A1"].Value = "ID";
excelApp.Range["B1"].Value = "Balance";
excelApp.Range["A2"].Select();

foreach (var ac in accounts)
{
    DisplayFunc(ac, excelApp.ActiveCell);
    excelApp.ActiveCell.Offset[1, 0].Select();
}
// Copy the results to the Clipboard.
excelApp.Range["A1:B3"].Copy();

excelApp.Columns[1].AutoFit();
excelApp.Columns[2].AutoFit();
}

I was able to develop this code based on searches. But I do not know if it fits this concept. Could you help me with that?

Classe DLL
using System;
using System.Security.Cryptography;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace PortalRH.DLL
{
[ComVisible(true), ClassInterface(ClassInterfaceType.None),
Guid("00AC4F7E-71B0-4BC7-AD8E-1175CD88457A")]
public class Criptografia : ICriptografia
{
    private string chave = "Exemplo";
    private string texto;
    public Criptografia(){}

    private static readonly byte[] initVectorBytes =    Encoding.ASCII.GetBytes("tu89geji340t89u2");

    // Esta constante é utilizado para determinar o tamanho da chave do algoritmo de encriptação.
    private const int keysize = 256;

    public static string Encrypt(string plainText, string passPhrase)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            byte[] cipherTextBytes = memoryStream.ToArray();
                            return Convert.ToBase64String(cipherTextBytes);
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText, string passPhrase)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }


    public string Matricula()
    {
        const string matricula = "5444";
        string plaintext = Encrypt(matricula, chave);
        return (plaintext);
    }

    public string Contrato()
    {
        const string contrato = "67334";
        string plaintext = Encrypt(contrato, chave);
        return (plaintext);
    }
}
}

My interface

using System.Runtime.InteropServices;
namespace PortalRH.DLL
{
[InterfaceType(ComInterfaceType.InterfaceIsDual),
 Guid("37DFD392-8BC3-4A08-B69A-5FDF1B6DF4B1")]
public interface ICriptografia
{

    string Matricula();
    string Contrato();
}
}
    
asked by anonymous 16.01.2015 / 20:13

1 answer

4

Apparently your code is correct, I will share my experience, C # interop with VB6 / C # (VS 2012) might help you in some details that are missing.

  • Open your project's properties (DLL) menu and follow the steps in the image below to configure your DLL.
  • Excerpt DLL source code interop:
  • [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Interop.MeuInteopId")]
    public class MinhaClass: IMinhaClass
    {
        public string Usuario { get; set; }
        public void Adicionar(MeuObj obj)
        {
             minhalista.Add(obj);            
        }
    }
    
    public string Pesquisar()
    {
        return "teste";
    }
    
  • Code snippet Interface
  • public interface IFarmPop
    {
        void Adicionar(MeuObj obj)
        string Usuario { set; get; }
    

    Obs: In my case only the methods that are in the interfaces are exposed in the interop, that is, when using the DLL in other applications, they will only have access to the methods that are in the Interface. **
    "Exposing" your DLL to the world!

    Within the development environment, you just need to reference your DLL, if you can, the methods exposed will be accessible. I do not know what language the other applications referred to in the question are, but the process is similar.

    In order for other applications to have access to your DLL (outside the development environment), you must register it with the Regasm tool.

      

    According to Microsoft: Regasm is a tool that enables COM clients   to create .NET Framework classes transparently. Since one   class is registered, any COM client can use it as if the class   was a COM class.   

    You can also use installers to register your interop DLL, but if you want to register via the command line follow the steps:

  • At the command prompt navigate to: C: \ Windows \ Microsoft.NET \ Framework \ " framwork version " (version you compiled your DLL)
  • Execute the command: regasm.exe SuaDLL.dll /register /codebase /tlb
  • 18.01.2015 / 03:59