.NET Forum / .NET Framework / Interop / February 2008
regasm /tlb complaints element not found
|
|
Thread rating:  |
michael sorens - 26 Dec 2007 20:06 GMT (I am a novice with interop services so bear with me...)
I have a legacy C# application and am using VS2005 to generate a dll for it. I want to make this available for COM access which requires, as I understand it, invoking both gacutil and regasm. I am getting this error from regasm:
> REGASM Ruby2net.dll /tlb:com.Ruby2net.tlb /verbose RegAsm : error RA0000 : Type library exporter encountered an error while processing 'Ruby2net.IRuby2net, Ruby2net'. Error: Element not found.
I also tried tlbexp and received the same error.
Even though this error is present, I have been able to call the classes via COM successfully. Until now, that is. My COM calls originate in a Ruby application that had been working fine. I changed some of the internals--nothing connected to the COM interface--and suddenly the ruby call
win32ole.new('Ruby2net.Ruby2netClass')
fails with "The system cannot find the file specified.".
So I am beginning to dig into this unfamiliar terrain. It seemed reasonable to start with the regasm error since it seems vaguely related (to my untrained eyes). I have been able to find a variety of sources on the steps needed to achieve com interop, but nothing on what would cause the regasm error I have encountered.
Any suggestions would be appreciated.
Walter Wang [MSFT] - 27 Dec 2007 06:58 GMT Hi,
Generating a type library for an assembly that references other assemblies may cause several type libraries to be generated at once. Is your .NET code referencing some other COM components? Would you please send me the source code of your .NET class so that I can reproduce the issue on my side?
For the second issue, I think this might be also related to the first one if you have installed the assembly in GAC.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
michael sorens - 27 Dec 2007 17:31 GMT I have sent under separate cover my sample project after I whittled it down to just a couple lines of code. I have also included in the package a file called "reg.bat" which is what I use to invoke gacutil and regasm. With this tiny DLL, here is the status: (1) The call to regasm still generates the "element not found" error. (2) The ruby -> com -> C# code executes properly.
As far as I observe, my .NET code is not calling other COM components.
michael sorens - 27 Dec 2007 20:06 GMT Some further results/questions--the final question is the most important:
(1) The regasm call continues to report "element not found" but as that does not seem to be impacting correct behavior, it is a lesser priority. (If my supposition is wrong--and it is causing incorrect behavior, then of course it is first priority.:-)
(2) When I accessed the .NET component via COM from ruby, I was observing (as originally reported) a failure on the win32ole.new() call indicating a file was not found (but it did not identify the file!). From experimentation I found that, instead of calling gacutil and regasm manually, as in : gacutil /f /i Ruby2net.dll regasm Ruby2net.dll /tlb:com.Ruby2net.tlb /verbose if I let VS2005 run regasm (by selecting the "Register for COM interop" option), then the COM call from ruby worked. QUESTION: Why this difference?
(3) My reading indicates that VS2005 is only running regasm, not gacutil (and I have confirmed this by checking that my library is *not* showing up in the GAC). QUESTION: So when does one also need to run gacutil?
(4) My COM call from ruby is not quite doing as well as I have led on :-). It accesses the C# code, but there is a problem in the Windows Communication Foundation (WCF) connection. It reports that it could not find the endpoint with the given name/contract. If I create a .NET stub client and call the same code it works properly, but only because I have given the client an app.config file that provides the correct signatures under the <system.serviceModel> node. QUESTION: So how do I provide the app.config (or otherwise provide WCF endpoint details) to the COM access path?
michael sorens - 27 Dec 2007 22:01 GMT Yet a further update:
I still would appreciate answers to my previous questions, but I was able to get my main issue resolved as I describe below.
I finally realized why my WCF connection was failing: As I stated, I had to give my .NET stub client a copy of the app.config file, which of course is not available when I access via COM. Having app.config in the class library project serves no function. So I simply translated the relevant portion of the app.config file to imperative code to define the binding, then passed that binding to the ChannelFactory. That alleviates the client (either .NET stub or COM interface) from needing the app.config file.
QUESTION: Is there any way to "compile in" the app.config file into my DLL (which I have attached to the library project in VS) so that I would not need the hard-coded solution above?
Walter Wang [MSFT] - 28 Dec 2007 05:04 GMT For the original issue, I've been able to reproduce the issue on my side. After researching, I've found that this issue is related to the GUID that you're using on the interface. Currently I'm not sure why this specific GUID "3d17c28b-a52d-46d4-b61c-adab63ee6118" doesn't work, but changing it to any other GUID will work.
For the other question about app.config, yes it will only be used if you name it after the main process name. If you are calling it from ruby, maybe renaming the .config file to ruby.exe.config might work but I haven't tested and this is actually not recommended. I think you might be able to embed the config file as a resource in your .NET assembly, then you could read it and pass the WCF part.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 28 Dec 2007 05:12 GMT OK, I just noticed that you're using the same GUID on the interface as in the Assembly:
[assembly: Guid("3d17c28b-a52d-46d4-b61c-adab63ee6118")]
This attribute will be used to determine the LibID in the generated type library and cannot be used as an interface's GUID, :)
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
michael sorens - 28 Dec 2007 16:34 GMT (1) I found that after I created a Settings file for my DLL, it generated myapp.dll.config and those values *were* accessible via Properties.Settings.Default.xxx even when calling from COM. But if I edited the myapp.dll.config file, the changes were ignored. I even tried rerunning the regasm comand guessing that maybe the myapp.dll.config file was somehow bundled with the dll, but the changes to the config file were still not seen. How could I get these changes to be seen?
(2) Do I need a Guid attribute on the class, the interface, and the assembly to expose this for COM access? How do I choose a proper Guid for each?
Tony Gravagno - 29 Dec 2007 02:48 GMT >(2) Do I need a Guid attribute on the class, the interface, and the assembly >to expose this for COM access? How do I choose a proper Guid for each? I have a managed class which implements two interfaces. Both of the interfaces have their own GUID and the derived class also has a different GUID. When you say "proper" I'm not sure what you mean, but in VS2005 you just go to Tools, Create GUID, and use the Registry Format, minus the {} braces.
I have an managed add-in working as an Excel UDF. It works fine on my development system but it's not deploying properly - seems the Setup Project doesn't include all of the registry entries, or maybe I need to use regasm with the tlb, like you're doing. The difference between my code and yours is that I have a COM shim between the Excel/COM client and my code.
If you'd like to see my setup, I've written a series of blogs on the topic - unfortunately after 6 articles I still don't have a successful deployment, but there are a lot of good references for anyone who is researching this area of interop. I've documented why shim's are supposed to be helpful for COM interop (with references) and exactly how to use the COM Shim Wizard from Microsoft (to the best of my knowledge).
HTH Tony
remove.mungeNebula-rnd.com/blog/tech/2007/12/excel-tools6.html
Please remove the anti-spam munge from the link.
Walter Wang [MSFT] - 02 Jan 2008 08:23 GMT Hi Michael,
The settings are accessible at first is because the default value are applied using attributes and saved in the assembly:
[global::System.Configuration.DefaultSettingValueAttribute("Hello")] public string Setting {
You can see properties like above in the Settings.Designer.cs file. These default values take effect when the application .config file is missing or no value is specified in the application configuration file. In this case, as I already pointed out, a .NET DLL cannot have its own configuration file, the .dll.config file has no effect at runtime.
For the GUID issue, if your COM client is using late-bind IDispatch, then you don't have to specify GUID values for the .NET class/interface. Also, there's no "Proper" GUID issue as long as they are not duplicated to existing GUIDs.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
michael sorens - 07 Jan 2008 20:25 GMT I peppered several questions into this one thread... Reviewing what I wrote, there was one question unanswered that I am curious about: As I mentioned, if I just select the "Register for COM interop" on the VS properties designer, then my connection works without putting the DLL in the GAC apparently. So when does one need to add a DLL to the GAC? A link to an intro on GAC usage would suffice, then I promise to stop protracting this thread :-)
Walter Wang [MSFT] - 08 Jan 2008 06:43 GMT When you're not putting the assembly in GAC, if it's also not strong-named, then it must be placed within the same directory as the COM client that uses this assembly via COM interop. Basically we have three types of scenario regarding .NET COM server:
* assembly is strong named, installed into GAC; use regasm without switch /codebase. Fusion will find the assembly from GAC. * assembly is strong named, not installed into GAC; use regasm with switch /codebase. Fusion will find the assembly from the location where it's registered. * assembly is not strong named (cannot be installed into GAC); you cannot use regasm with switch /codebase. This time it can only be used by COM clients that in the same directory as this assembly.
For .NET Fusion, Richard Grimes has an excellent online workshop:
http://www.grimes.demon.co.uk/workshops/fusionWS.htm
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Elizabeth Connolly - 29 Feb 2008 23:26 GMT I am having perhaps a similar problem. I have a .Net (2.0) assembly that I want to call using a Com client (a VB6 program) on another machine. I don't need it to be strong-named or in the GAC - the assembly will be in the same directory as the Com client.
So, based on various examples from googling, my process has been:
1. Make sure that the assembly [call it MyAssy.dll] has ComVisiible attribute set, and use both an interface and a class that implements the interface. 2. Make sure that the assembly, the interface and the class are all decorated with GUID attributes, and the Interface also has a ComVisible = true attribute. 3. Build the .Net assembly. 4. On the .Net machine, regasm MyAssy.dll /tlb:MyAssy.TLB. This succeeds, and I copy both the dll and the type library to the VB6 machine with .Net 2.0 framework installed. 5. Again, regasm MyAssy.dll /tlb:MyAssy.TLB (with correct paths everywhere.) 6. Open the VB project and add the reference to the type library. In the VB6 project I can now see the class and Intellisense shows me all its methods. So far so good. 7. However, when I try to compile, I get Run-time error -2147024894 (800700002) Automation Error - Cannot find the file specified.
The GUIDs in the registry appear to match the GUID for my class and the Type library. I have numerous times removed references, unregistered, verified that the GUIDs are gone from the registry, reregistered, and many other things but have not been able to solve this problem. Even more annoying, I did a proof-of-concept of this whole process several months ago, and it worked fine, and continues to work, on the same 2 machines. The difference here is that MyAssy.dll actually wraps another .Net DLL that actually does something, but even when I temporarily removed the reference to the other .Net DLL from MyAssy.dll, I had the same problem.
Any idea what I am doing wrong?
Thanks much,
\Elizabeth
> When you're not putting the assembly in GAC, if it's also not > strong-named, [quoted text clipped - 26 lines] > This posting is provided "AS IS" with no warranties, and confers no > rights. Elizabeth Connolly - 29 Feb 2008 23:30 GMT I forgot to say - the problem in building appears at the line in which I try to instantiate an object provided by MyAssy.dll.
>I am having perhaps a similar problem. I have a .Net (2.0) assembly that I >want to call using a Com client (a VB6 program) on another machine. I don't [quoted text clipped - 68 lines] >> This posting is provided "AS IS" with no warranties, and confers no >> rights.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|