none
Registering my dll on an other PC RRS feed

  • Question

  • I have written two functions under C# in the Visual Studio 2013 for calling it from Excel 2010.  I built the Library, I set the properties "Make Assembly COM visible" and "Register for COM Interop". 

    After Building the DLL was created, and I can use the functions in it by my Excel VBA program without any problem.

    But I'd like to use the functions on other machines too. And here comes my problem with the registering. 

    The first step was OK with the regasm: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm.exe "C:\Windows\System32\MyProgram.dll" /tlb: MyProgram.tlb 

    But I couldn't realize the second step: regsvr32 "C:\Windows\System32\MyProgram.dll". It told me, that it doesn't find the entry point, the DllRegisterServer.

    After this trial of registering I can find the name of the dll file in the reference list of the Excel. The Excel recognizes it too in the VBA line: Dim testClass As New MyProgram.xxxxx (I mean, it is so because of regasm)

    But it can't see the functions inside the dll. (I mean it is so because the wrong use of regsvr32)

    What do I make wrong? Does something missing from the source code? I don't think, because Visual Studio is able to register the dll during the building process. 

    Or should I change something in the properties or the references of my project?

    Or something else?

    • Moved by CoolDadTx Thursday, February 19, 2015 6:19 PM Office related
    Thursday, February 19, 2015 4:42 PM

Answers

  • .NET 4.5 and .NET 4.0 share the same CLR so, unless you're relying on features that aren't available then it should be fine. 

    You didn't post your addin code but assuming you have declaratively specified the GUIDs for the TypeLib and COM class you're exposing then rebuilding shouldn't change any of the COM registration values.  However if you didn't explicitly set this info up then each time you rebuild it'll generate new COM registration.  Once you've rebuilt you cannot unregister the old version (as that data is gone).  Hence you'll end up with conflicts. You should generally unregister the COM component before you rebuild it to avoid this issue or (preferably) ensure that you've explicitly provided the GUIDs for the COM visible components so that the registration information doesn't change.

    Friday, February 20, 2015 2:41 PM
  • Gacutil has nothing to do with COM.  Gacutil is the tool used to work with the GAC.  Only strongly named assemblies can appear in the GAC.  The GAC is a useful place for storing commonly needed files but versioning suddenly becomes very important when using the GAC.

    Wednesday, February 25, 2015 2:40 PM

All replies

  • You don't use regsvr32 on a managed assembly.  Using regasm is all you need to do.

    As for why the functions don't show up I don't know so I'll move this post to the Office forums where they can help you with that specific issue.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    Thursday, February 19, 2015 6:19 PM
  • Thanky Michael!

    Can you give me the adress of the Office forum, where you moved my post? Because I'm not sure that I1ll get an automatic message about the answers.

    Imre

    Thursday, February 19, 2015 8:18 PM
  • Pardon. I wanted to write: Thank you Michael!

    Thursday, February 19, 2015 8:18 PM
  • Your forum threads will give you the correct URL where your thread is at.  You will get an email for any answers irrelevant of where the thread is moved too.  You should get an email for this response and the thread title will take you to the correct URL (https://social.msdn.microsoft.com/Forums/office/en-US/a0f84431-fddb-4ff5-aaa2-4fbd493ada57/registering-my-dll-on-an-other-pc?forum=exceldev).
    Thursday, February 19, 2015 8:27 PM
  • Thank you.

    Thursday, February 19, 2015 9:13 PM
  • Hi pimre,

    According to the description, you were create an managed assembly and make it com visible.

    >>But it can't see the functions inside the dll. (I mean it is so because the wrong use of regsvr32)<<

    Colud the code work well? Did you mean that the intellisese in VBEditor doesn't work?

    If I understand correctly, did the intellisese work when you call the function in the manage assemble from C++?

    If it also dosen't work, I suspect this the issue may relative the to the assemble you are building.

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, February 20, 2015 3:26 AM
    Moderator
  • Hi Fei,

    The code worked well on the machine where I built the dll.

    I didn't have any problem with the intellisense in the VBA editor.

    I didn't work wit C++. I worked with C#

    It is possible that I have my problems from the different .NET Framework systems. I built the program with the Version 4.5 and on the target machine I have only the .Net Framework Version 4.0. 
    So I'm just trying to rebuild the dll with the Target Framework 4.0. But I still have some difficulties with unregistering and registering the dll again on the other machine,

    Friday, February 20, 2015 10:15 AM
  • .NET 4.5 and .NET 4.0 share the same CLR so, unless you're relying on features that aren't available then it should be fine. 

    You didn't post your addin code but assuming you have declaratively specified the GUIDs for the TypeLib and COM class you're exposing then rebuilding shouldn't change any of the COM registration values.  However if you didn't explicitly set this info up then each time you rebuild it'll generate new COM registration.  Once you've rebuilt you cannot unregister the old version (as that data is gone).  Hence you'll end up with conflicts. You should generally unregister the COM component before you rebuild it to avoid this issue or (preferably) ensure that you've explicitly provided the GUIDs for the COM visible components so that the registration information doesn't change.

    Friday, February 20, 2015 2:41 PM
  • Thank you again Michael!

     

    Excuse me for answering so late. I was first glad of your answer, I thought that the reason of my problem is caused by ignoring the specification of the GUID. Especially, because there was one only time (the very next morning after your first answer), as my generated code could run on my other machine. But I wanted to test  the process again. And since that it didn't work again. On my source computer, where I build and rebuild the code there is no problem, it works.

    I checked now my Visual Studio 2013 and I found that it gives a GUID code for the assembly, and it doesn't change it even if I change the source code.

    But I'm think it is better to follow your advice, I send here the frame of my code, and ask you where and how should I put the GUID code.  And it it can't be excluded that I have some other mistakes too. I'm a beginner in C# and in Visual Studio too.

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Security.Cryptography;
    
    namespace SecretLibrary
    {
        public   class EncryptionExtensions
        {
            public string password = "something";
            public string Encrypt(string secret) 
            { // here is the code of the Encript funcion
            }
    
            public   string Decrypt(  string secret) // , string password)
            {// here is the code of the Decript funcion
            }
        }
    }
    


    Sunday, February 22, 2015 10:47 PM
  • In general the recommendation for exposing COM objects to COM is to only expose the class(es) and methods that are actually needed by COM.  In order to be callable from COM the class must be marked as ComVisible.  It is generally not a good idea to mark the entire assembly as such except when creating a PIA. So you should apply this attribute only to the item(s) that need to be exposed. This would include your COM class. Since the COM class is exposed it should also get a GUID using Guid.

    Looking at your code, this doesn't really appear to be anything that you'd be exposing via COM but I'll go with it anyway.

    [ComVisible(true)]
    [Guid("827ECC5A-19DC-4B5B-88E7-AD1F8CE4A4D0")]
    public class EncryptionExtensions
    { }

    Now this just defines the COM class.  COM is interface based so every COM class must implement a COM interface.  If you don't define one then the compiler generates one for you which can cause: a) the interface to change as the code evolves, and b) methods to be exposed that you don't want.  Therefore you should always define an interface that is also COM visible that the COM class implements.

    [ComVisible(true)]
    [Guid("BDFF36E5-1BFC-4431-B5B3-C60ECCF5F6AF")]
    public interface IEncryptionExtensions
    {
        string Encrypt ( string secret );
        string Decrypt ( string secret );
    }
    
    ...
    [ClassInterface(ClassInterfaceType.None)] public class EncryptionExtensions : IEncryptionExtensions {}

    The interface itself needs to either implement IUnknown or IDispatch (or both) in order to work with COM.  Since you mentioned being an Office addin it is probable that you'll want IDispatch.

    ...
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IEncryptionExtensions
    { }

    You may optionally include the ProgId attribute on the COM class if you want to use a custom Prog ID rather than a system generated one.  That should take care of the class and interface.

    For the assembly you should ensure the Guid attribute is applied to the assembly (it is by default). Again, you should only make the entire assembly COM visible if it is a PIA.

    //In AssemblyInfo.cs
    [assembly: Guid("ef360ad4-6f2a-42a0-94de-37d9a1f93821")]

    This should minimize the changes between build of your app. Some things will change but this should allow you to unregister and re-register your app without too much junk being left in the registry.

    Sunday, February 22, 2015 11:44 PM
  • I tried to follow your advice but I'm not sure that I understood you correctly. My program look now like this:

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
     
    [ComVisible(true)]
    [Guid("BDFF36E5-1BFC-4431-B5B3-C60ECCF5F6AF")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IEncryptionExtensions
    { 
        string Encrypt(string secret);
        string Decrypt(string secret);
    }
     
    namespace SecretLibrary
    {
        [ClassInterface(ClassInterfaceType.None)]
        [ComVisible(true)]
        [Guid("827ECC5A-19DC-4B5B-88E7-AD1F8CE4A4D0")]
        public class EncryptionExtensions : IEncryptionExtensions
        {
            public string Encrypt(string secret)
            { 
                     // here is the code of the Encrypt function
                   }
    
      public string Decrypt(string secret)
            {
                     // here is the code of the Decrypt function
      }
        }
    }

    After building it works. The Visual Studio registers the program in the directory of its own project.
    And with its automatic registration my Excel program can work without any problem-

    But I want to carry the program. For that reason I unregistered it (As Administrator of course) this way: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm.exe "D:\Dokuments\Visual Studio 2013\Projects\SecretLibrary\SecretLibrary\bin\Debug\SecretLibrary.dll" /tlb:SecretLibrary.tlb /unregister. 

    Then I copied the dll file to the system32 directory and registered it: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm.exe "C:\Windows\System32\SecretLibrary.dll" /tlb:SecretLibrary.tlb. The registration was successful.

    After Opening the Excel VBA I could see in the reference list the SecretLibrary and I could see also that it was in the C:\Windows\System32 directory.

    But after relocating the library file the Excel can't recognize the functions in the dll. I get the error message: Automation error. The system cannot find the file specified.

    At last I made one more test. I unregistered the Library from the system32 and registered it again in the Visual Studio Library. And this time the Excel program shown me the same error message with the automation error. 

    Is it possible that there are some problems with my registration too?

    Tuesday, February 24, 2015 8:04 PM
  • Are you running a Window x64 machine? If so then remember that Windows\System32 is for 64-bit apps. 32-bit DLLs go into SysWow64. But putting your DLL into the system path isn't the correct solution anyway. That isn't how COM works nor is it how .NET works. Put your assembly in a directory appropriate for your application (often Program Files (x86)\<company>\<product> and then register your COM object. Once register apps will find the assembly. Also bear in mind that you need to register your assembly using the x86 version of regasm so that x86 apps can find it.
    Tuesday, February 24, 2015 10:34 PM
  • I don't use Windows x64, only x32. I'm agreed that it isn't the best solution to put the DLL into the system path, but I wanted to allow other people to use the Excel program too. That is why I looked for a place that can be found on most of the machines. 

    My Microsoft .NET system is automatically installed by setting up my System. So I can't imagine that my regasm could be something else than x86.

    I'm very sorry that I can't register my DLL, and on the other side it's funny that I am able to corrupt the by the Visual Studio registered DLL by unregistering and registering again. One step of my registering process must be missing or mistaken.

    Anyway thank you for your help.

    Wednesday, February 25, 2015 6:30 AM
  • Zap!

    I was searching on google with the keywords "registering managed assembly" and found this article. I don't know how gacutil.exe works so I tried first using regasm.exe with the syntax that I wrote here yesterday but I added the parameter /codebase to it. The program sent me the warning that an unsigned assembly can cause my assembly to interfere with other applications but it registered my DLL and it resolved my problems. The Excel could use my functions and I was able to carry the DLL to an other machine too, where it also worked after the registering with the /codebase parameter.

    I don't know what is the correct way of signing or using gacutil.exe instead. Or can I negligate the warning because I use the DLL only in one program that will be used very seldom?

    Wednesday, February 25, 2015 10:21 AM
  • Gacutil has nothing to do with COM.  Gacutil is the tool used to work with the GAC.  Only strongly named assemblies can appear in the GAC.  The GAC is a useful place for storing commonly needed files but versioning suddenly becomes very important when using the GAC.

    Wednesday, February 25, 2015 2:40 PM
  • Thank you for this too. 

    I think with your help I could solve my problem. I could improve my code and I could register my DLL.

    Thank you for that all.


    Friday, February 27, 2015 6:53 PM