Search This Blog

Showing posts with label COM. Show all posts
Showing posts with label COM. Show all posts

Friday, July 17, 2009

VB6 App with C# COM object

VB6 project using C# COM Assembly
-2147024896 (80070002) Automation error The System cannot find file specified

I get this very thing...

from MSDN forum

Question:
i'm having problems running the vb6 app, and the error occurs when i make the form show. i've followed the instructions from the help file and still the problem arises everytime.

here's another weird thing, when i added the interop form to an existing vb6 application, it was ok when run inside the ide. when i compiled this to an .exe file, the error happened. i also tried creating fresh vb6 app and it worked, so any ideas on this issue? thanks.


Answer:
1) Strongly name Assemblies.
   sn -k TestKeyPair.snk
2) Add TestKeyPair.snk to project(s).
3) Edit AssemblyInfo.cs
A) Make assembly is versioned
[assembly: AssemblyVersion("1.0.0.0")]
b) Add [assembly: AssemblyKeyFile("TestKeyPair.snk")]
4) Add Assembly to GAC
gacutil /i MyInterop.dll
- Make sure all Assembly DLLS has been
5) Regasm Assembly and expose COM use /codebase
REGASM MyInterop.dll /tlb:com.MyInterop.tlb /codebase
Better Answer:
1) Strongly name Assemblies.
   sn -k TestKeyPair.snk
2) Add TestKeyPair.snk to project(s).
3) Edit AssemblyInfo.cs
A) Make assembly is versioned
[assembly: AssemblyVersion("1.0.0.0")]
b) Add [assembly: AssemblyKeyFile("TestKeyPair.snk")]
4) Copied all related assemblies local to folder containing VB6 project
5) Run from this folder: tlbexp sampleDLL.dll /out:sampleDLL.tlb
6) run from this folder: regasm sampleDLL.dll /tlb:sampleDLL.tlb
7) Open VB6 project and reference to sampleDLL.tlb is local to project.

Friday, July 10, 2009

Create COM object using C# for VB6 Application

Here is a C# example: Create a COM object with events using C# and implement in a VB6 Application.

Step #1: Define COM interfaces
Need to create two interfaces - 1 class interface and a events interface

Public Class Interface: IMyClass
using System;
using System.Drawing;
using PicasaBloggerUserControls;
using System.Runtime.InteropServices;

namespace MyApp
{
[Guid("xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface
IMyClass
{
void GetDRCUpdate(string url, int majorVer, int minorVer, int RevisionVer, bool GetLatest);
}
}


Public Interface defining the events: IMyClassEvents

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace MyApp
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
public interface
IMyClassEvents
{
void DownloadComplete();
void DownloadCancel(bool downloadfailed);
}
}
Step #2
Define Public class using class interface: winformUI

using System.Drawing;
using System.Windows.Forms;
using PicasaBloggerUserControls;
using System.Runtime.InteropServices;

namespace PicasaBloggerUI
{
[Guid(
"xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
[
ComSourceInterfaces("MyApp.PicasaBloggerEventsInterface"),
ClassInterface(ClassInterfaceType.None)
]
[ProgId("winformUI")]


public class winformUI :
IMyClass
{
public event FileDownloadDelegate DRCDownloadComplete;
public delegate void FileDownloadDelegate();

public event FileDownloadCancelDelegate DRCDownloadCancel;
public delegate void FileDownloadCancelDelegate(bool downloadfailed);

private frmDRCUpdate _DRCUpdater;

//ctor
public winformUI()
{
_DRCUpdater = new frmDRCUpdate();
_DRCUpdater.OnFileDownload += new frmDRCUpdate.FileDownloadDelegate(_DRCUpdater_OnFileDownload);
_DRCUpdater.OnFileDownloadCancel += new frmDRCUpdate.FileDownloadCancelDelegate(_DRCUpdater_OnFileDownloadCancel);
}

void _DRCUpdater_OnFileDownloadCancel()
{
if (null != DRCDownloadCancel)
{
DRCDownloadCancel(!_DRCUpdater.Successful);
}
}

void _DRCUpdater_OnFileDownload()
{
try
{
//MessageBox.Show("Download Successful");
DRCDownloadComplete();
}
catch
{
}

}

void IPicasaBlogger.GetDRCUpdate(string url, int majorVer, int minorVer, int RevisionVer, bool GetLatest)
{
_DRCUpdater = new frmDRCUpdate();
_DRCUpdater.OnFileDownload += new frmDRCUpdate.FileDownloadDelegate(_DRCUpdater_OnFileDownload);
_DRCUpdater.OnFileDownloadCancel += new frmDRCUpdate.FileDownloadCancelDelegate(_DRCUpdater_OnFileDownloadCancel);
_DRCUpdater.Show();
_DRCUpdater.GetDRCUpdate(url, majorVer, minorVer, RevisionVer, GetLatest);
}

}
}

Step #3 Compile C# code and register the assembly:
REGASM MyApp.dll /tlb:com.MyApp.tlb
Now you are ready to add the COM object as a reference to a VB project.
1) Open VB6 project, select references and browse to locate of MyApp.tlb and add as a reference.

In a VB6 form Module
Private WithEvents oMyAppUI As MyApp.winformUI

Private Sub Form_Load()
Set oMyAppUI = New MyApp.winformUI
End Sub

Private Sub oMyAppUI_DownloadCancel(ByVal downloadfailed As Boolean)
If downloadfailed Then
MsgBox "Update Failed, please try again. If the failure persists, contact me at Gary.Kindel@gmail.com for assistance.", vbOKOnly
Else
MsgBox "You have the current version, no updates are available.", vbExclamation
End If
End Sub
Private Sub oMyAppUI_DownloadComplete()
If MsgBox("Do you want to exit and install the update?", vbYesNoCancel, "Exit DRC and run Update file") = vbYes Then
mApplyUpdate = True
Unload Me
End If
End Sub