COM Interop question in .NET 2.0

E

Erik

Thank you for your answer, but I'm afraid that didn't help. Now the
code looks like this:

using System;
using System.Collections.Generic;
using System.Text;

namespace Com_test
{
public class Class1
{
public Class1() { }
}
}

but it still cannot be registered for COM interop.
 
W

Willy Denoyette [MVP]

Erik said:
Thank you for your answer, but I'm afraid that didn't help. Now the
code looks like this:

using System;
using System.Collections.Generic;
using System.Text;

namespace Com_test
{
public class Class1
{
public Class1() { }
}
}

but it still cannot be registered for COM interop.

It should, what error are you getting?

The simplest way to test this is compile the file from the command line
using:

csc /t:library filename.cs
and register with:
regasm /codebase /tlb filename.dll
unregister with:
regasm /unregister /tlb filename.dll



Willy.
 
W

Willy Denoyette [MVP]

You said you couldn't register, now you are teling me you could't compile!
A C# class needs to obey a number of rules (imposed by COM), one of the is
a default public construcor, but there are others.
A public constructor is in general all you need to be able to create an
instance, that doesn't mean that methods are callable. As I said your class
can be instantiated, but your methods are not callable from a native COM
client itself, the fact it works in your case is because you methods
OnCreate and OnClick are not called from COM, they are called from the
container (they are event handlers right?) .


Willy.
 
G

Guest

Hi Willy,

Yes, i wasnt able to compile. I am sorry if i had misrepresentd in
previously. Also my OnCreate and OnClick functions are in fact getting called
by event handlers. Can you let me know where i can read up on the rules my c#
class needs to foolow in order to be callable from COM.

Thank You,
Vish
 
G

Guest

I hate dredging this up as its so old, but thought i'd clear this up. After
spending the past 3 days trying everything possible to get my C# code to work
in COM, i almost gave up until seeing this post.

To put it bluntly, the documentation is wrong.

The code i was using in 1.1 DID NOT WORK in 2.0. Simple test case below:

---------- BEGIN ITVTest.cs ----------
using System;
using System.Text;
using System.Runtime.InteropServices;

namespace comitvtest
{
[Guid("3A8E1A9D-206E-48cb-BD4F-0FE6D3155CDF")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class ITVTest : IITVTest
{
public ITVTest()
{
throw new System.NotImplementedException();
}

public int GetCurrentHour()
{
return System.DateTime.Now.Hour;
}
}
}

---------- END ITVTest.cs ----------


---------- BEGIN IITVTest.cs ----------
using System;
using System.Runtime.InteropServices;
namespace comitvtest
{
[Guid("770A5441-1B1D-4847-91B5-B84EDDC1B647")]
interface IITVTest
{
int GetCurrentHour();
}
}
---------- END IITVTest.cs ----------


--- Project Setup ---
Goto Project -> Properties
Click the "Build" tab.
Select the Register for COM Interop option

Click the "Signing" tab.
Select "Sign the Assembly", from the file name select "<new>" give it a name
i used KeyPairing.snk with NO password


Build project
start -> run: cmd

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

H:\>c:

C:\>cd projects\com.itv.test

C:\Projects\com.itv.test\bin\Release>tlbexp com.itv.test.dll
Microsoft (R) .NET Framework Assembly to Type Library Converter 2.0.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.

Assembly exported to 'C:\Projects\com.itv.test\bin\Release\com.itv.test.tlb'

C:\Projects\com.itv.test\bin\Release>regasm com.itv.test.dll
/tlb:com.itv.test.t
lb
Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.42
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

Assembly exported to
'C:\Projects\com.itv.test\bin\Release\com.itv.test.tlb', an
d the type library was registered successfully

--- Visual Basic 6 Test ---
Create new Standard EXE project
Goto to Project menu, select References
Find the com assembly in references list (com_itv_test), select, and hit OK
View the object browser
Types are visible here. (can also do the same with with Visual FoxPro's
Class Explorer and open the TLB file.)


--- The Proof ---
Now try it without the ComVisible attribute.


- Mark Harris



C:\Projects\com.itv.test>cd bin/release
Willy Denoyette said:
Sorry, but this is not a complete sample (missing BaseCommand), so there is
lttle I can do with it, but trust me [ComVisible(true)] IS the default.

I'm also not entirely clear on the purpose is of this class for a COM
client, true, this object creatable from COM clients, but none of it's
methods are callable.


Willy.

Vish said:
Hi,

Ok. I am not sure why but it did fix the issue. Obviously y'all know more
on
this subject than i do. But i am posting my code below if y'all are still
interested.

[ClassInterface(ClassInterfaceType.None)]
[Guid("8D0240AD-1BBE-4831-8214-39DD46A4A797")]
[ComVisible(true)]
public sealed class TestTool : BaseCommand
{
private IApplication m_app;

public override void OnCreate(object hook)
{
if (hook != null)
{
if (hook is IMxApplication)
{
m_app = (IApplication)hook;
}
}
}

public override void OnClick()
{
IMxDocument mxDoc = (IMxDocument)m_app.Document;
IActiveView activeView = mxDoc.ActiveView;
activeView.Extent = activeView.FullExtent;
activeView.Refresh();
}

public TestTool()
{
base.m_category = "Vish's Test";
base.m_caption = "Full Extent C#";
base.m_message = "Zooms the display to its full extent";
base.m_toolTip = "Full Extent C#";
base.m_name = "Developer Samples_FullExtent C#";

string[] res = GetType().Assembly.GetManifestResourceNames();
if (res.GetLength(0) > 0)
{
base.m_bitmap = new
System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream(res[0]));
}
}

#region Component Category Registration

[ComRegisterFunction()]
[ComVisible(false)]
static void RegisterFunction(String regKey)
{
MxCommands.Register(regKey);
}

[ComUnregisterFunction()]
[ComVisible(false)]
static void UnregisterFunction(String regKey)
{
MxCommands.Unregister(regKey);
}

#endregion
}
















Willy Denoyette said:
Yeah I know it's always been default because it's bitten me in the
rear-end a few times ;-). I honestly didn't think that they would have
made a breaking change like that. So the question that still remains,
did
setting [ComVisible(true)] really solve the problem or was it something
else?


Jason Newell



Pretty sure it was something else (my guess: missing public on the
class).

Willy.
 
W

Willy Denoyette [MVP]

The default ComVisible attribute value did not change, what did change in
VS2005 was the AssemblyInfo.cs file which now contains [assembly:
ComVisible(false)]. But, the default (that is whan the attribute is not
specified) is still true.


Willy.

|I hate dredging this up as its so old, but thought i'd clear this up. After
| spending the past 3 days trying everything possible to get my C# code to
work
| in COM, i almost gave up until seeing this post.
|
| To put it bluntly, the documentation is wrong.
|
| The code i was using in 1.1 DID NOT WORK in 2.0. Simple test case below:
|
| ---------- BEGIN ITVTest.cs ----------
| using System;
| using System.Text;
| using System.Runtime.InteropServices;
|
| namespace comitvtest
| {
| [Guid("3A8E1A9D-206E-48cb-BD4F-0FE6D3155CDF")]
| [ClassInterface(ClassInterfaceType.AutoDual)]
| [ComVisible(true)]
| public class ITVTest : IITVTest
| {
| public ITVTest()
| {
| throw new System.NotImplementedException();
| }
|
| public int GetCurrentHour()
| {
| return System.DateTime.Now.Hour;
| }
| }
| }
|
| ---------- END ITVTest.cs ----------
|
|
| ---------- BEGIN IITVTest.cs ----------
| using System;
| using System.Runtime.InteropServices;
| namespace comitvtest
| {
| [Guid("770A5441-1B1D-4847-91B5-B84EDDC1B647")]
| interface IITVTest
| {
| int GetCurrentHour();
| }
| }
| ---------- END IITVTest.cs ----------
|
|
| --- Project Setup ---
| Goto Project -> Properties
| Click the "Build" tab.
| Select the Register for COM Interop option
|
| Click the "Signing" tab.
| Select "Sign the Assembly", from the file name select "<new>" give it a
name
| i used KeyPairing.snk with NO password
|
|
| Build project
| start -> run: cmd
|
| Microsoft Windows XP [Version 5.1.2600]
| (C) Copyright 1985-2001 Microsoft Corp.
|
| H:\>c:
|
| C:\>cd projects\com.itv.test
|
| C:\Projects\com.itv.test\bin\Release>tlbexp com.itv.test.dll
| Microsoft (R) .NET Framework Assembly to Type Library Converter
2.0.50727.42
| Copyright (C) Microsoft Corporation. All rights reserved.
|
| Assembly exported to
'C:\Projects\com.itv.test\bin\Release\com.itv.test.tlb'
|
| C:\Projects\com.itv.test\bin\Release>regasm com.itv.test.dll
| /tlb:com.itv.test.t
| lb
| Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.42
| Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.
|
| Assembly exported to
| 'C:\Projects\com.itv.test\bin\Release\com.itv.test.tlb', an
| d the type library was registered successfully
|
| --- Visual Basic 6 Test ---
| Create new Standard EXE project
| Goto to Project menu, select References
| Find the com assembly in references list (com_itv_test), select, and hit
OK
| View the object browser
| Types are visible here. (can also do the same with with Visual FoxPro's
| Class Explorer and open the TLB file.)
|
|
| --- The Proof ---
| Now try it without the ComVisible attribute.
|
|
| - Mark Harris
|
|
|
| C:\Projects\com.itv.test>cd bin/release
| "Willy Denoyette [MVP]" wrote:
|
| > Sorry, but this is not a complete sample (missing BaseCommand), so there
is
| > lttle I can do with it, but trust me [ComVisible(true)] IS the default.
| >
| > I'm also not entirely clear on the purpose is of this class for a COM
| > client, true, this object creatable from COM clients, but none of it's
| > methods are callable.
| >
| >
| > Willy.
| >
| > | > > Hi,
| > >
| > > Ok. I am not sure why but it did fix the issue. Obviously y'all know
more
| > > on
| > > this subject than i do. But i am posting my code below if y'all are
still
| > > interested.
| > >
| > > [ClassInterface(ClassInterfaceType.None)]
| > > [Guid("8D0240AD-1BBE-4831-8214-39DD46A4A797")]
| > > [ComVisible(true)]
| > > public sealed class TestTool : BaseCommand
| > > {
| > > private IApplication m_app;
| > >
| > > public override void OnCreate(object hook)
| > > {
| > > if (hook != null)
| > > {
| > > if (hook is IMxApplication)
| > > {
| > > m_app = (IApplication)hook;
| > > }
| > > }
| > > }
| > >
| > > public override void OnClick()
| > > {
| > > IMxDocument mxDoc = (IMxDocument)m_app.Document;
| > > IActiveView activeView = mxDoc.ActiveView;
| > > activeView.Extent = activeView.FullExtent;
| > > activeView.Refresh();
| > > }
| > >
| > > public TestTool()
| > > {
| > > base.m_category = "Vish's Test";
| > > base.m_caption = "Full Extent C#";
| > > base.m_message = "Zooms the display to its full extent";
| > > base.m_toolTip = "Full Extent C#";
| > > base.m_name = "Developer Samples_FullExtent C#";
| > >
| > > string[] res =
GetType().Assembly.GetManifestResourceNames();
| > > if (res.GetLength(0) > 0)
| > > {
| > > base.m_bitmap = new
| > >
System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream(res[0]));
| > > }
| > > }
| > >
| > > #region Component Category Registration
| > >
| > > [ComRegisterFunction()]
| > > [ComVisible(false)]
| > > static void RegisterFunction(String regKey)
| > > {
| > > MxCommands.Register(regKey);
| > > }
| > >
| > > [ComUnregisterFunction()]
| > > [ComVisible(false)]
| > > static void UnregisterFunction(String regKey)
| > > {
| > > MxCommands.Unregister(regKey);
| > > }
| > >
| > > #endregion
| > > }
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > >
| > > "Willy Denoyette [MVP]" wrote:
| > >
| > >>
| > >> | > >> > Yeah I know it's always been default because it's bitten me in the
| > >> > rear-end a few times ;-). I honestly didn't think that they would
have
| > >> > made a breaking change like that. So the question that still
remains,
| > >> > did
| > >> > setting [ComVisible(true)] really solve the problem or was it
something
| > >> > else?
| > >> >
| > >> >
| > >> > Jason Newell
| > >> >
| > >> >
| > >>
| > >> Pretty sure it was something else (my guess: missing public on the
| > >> class).
| > >>
| > >> Willy.
| > >>
| > >>
| > >>
| > >>
| > >>
| >
| >
| >
 
S

Sara Carnell

Jason, if you could e-mail me at my e-mail address that would be
wonderful.
Sara
 
Joined
May 29, 2014
Messages
1
Reaction score
0
Hi Everyone...
I am trying to register a .dll file in COM.But it is failing and warnings are coming:


C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(935,9): warning MSB3391: "c:\users\acd92078.myttl\documents\visual studio 2010\Projects\SWADDIN_Test\SWADDIN_Test\bin\Debug\SWADDIN_Test.dll" does not contain any types that can be unregistered for COM Interop.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3341,9): warning MSB3214: "c:\users\acd92078.myttl\documents\visual studio 2010\Projects\SWADDIN_Test\SWADDIN_Test\bin\Debug\SWADDIN_Test.dll" does not contain any types that can be registered for COM Interop.


I have tried all the suggestions that were given previously in one of the discussions on similar error on PC review.


This is my Code:-

using System;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;
using SolidWorksTools;
using SolidWorksTools.File;
using System.Runtime.InteropServices;


using System.Diagnostics;

namespace SWADDIN_Test
{

[ComVisible(true)]
[Guid("6701cbb8-ee73-46ed-bbe5-8a80c9a0280b")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
interface ISWIntegration
{
void DoSWIntegration();
}//end of interface Dummy ISWIntegration

[Guid("6701cbb8-ee73-46ed-bbe5-8a80c9a0280b")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("SWADDIN_Test.SWIntegration")]
[ComVisible(true)]
public class SWIntegration : ISwAddin, ISWIntegration
{
public SldWorks mSWApplication;
private int mSWCookie;

public SWIntegration()
{ }//end of parametereless constructor

public void DoSWIntegration()
{ }//end of dummy method DoSWIntegration

public bool ConnectToSW(object ThisSW, int Cookie)
{
mSWApplication = (SldWorks)ThisSW;
mSWCookie = Cookie;
// Set-up add-in call back info
bool result = mSWApplication.SetAddinCallbackInfo(0, this, Cookie);
this.UISetup();
return true;
}//end of method ConnectToSW()

public bool DisconnectFromSW()
{
return UITeardown();
}//end of method DisconnectFromSW()

public void UISetup()
{ }//end of method UISetup()

public bool UITeardown()
{
return true;
}//end of method UITeardown()

[ComRegisterFunction()]//Attribute
private static void ComRegister(Type t)
{
string keyPath = String.Format(@"SOFTWARE\SolidWorks\AddIns\{0:b}", t.GUID);
using (Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(keyPath))
{
rk.SetValue(null, 1);// Load at startup
rk.SetValue("Title", "Abhijit's SwAddin"); // Title
rk.SetValue("Description", "All your pixels now belong to us"); // Description
}//end of using statement
}//end of method ComRegister()

[ComUnregisterFunction()]//Attribute
private static void ComUnregister(Type t)
{
string keyPath = String.Format(@"SOFTWARE\SolidWorks\AddIns\{0:b}", t.GUID);
Microsoft.Win32.Registry.LocalMachine.DeleteSubKeyTree(keyPath);
}//end of method ComUnregister()

}//end of class SWIntegration
}//end of namespace SWADDIN_Test


Kindly suggest me a solution on this.
Thanks in advance.
-Abhijit
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top