Custom Wizard Engine problem (C#)

  • Thread starter Thread starter Mr. Mountain
  • Start date Start date
M

Mr. Mountain

Hi,
I am building a custom wizard engine in C# following the example in
"Mastering Visual Studio.NET" by Griffiths, Flanders and Sells (pg 304).
Unfortunately, I'm having several problems that the book isn't helping me
overcome. (It is a good book, but O'Reilly hasn't made code available and so
far not a single example I've tried from the book has worked!)

To build a COM server in C# that implements the IDTWizard interface, does
the assembly have to have a strong name? The book says yes. However, the
MSDN page at
http://msdn.microsoft.com/library/d.../en-us/dv_vstechart/html/customprojectwiz.asp
indicates otherwise. The MSDN example shows only the following changes to
AssemblyInfo.cs:

//COM+ related settings
//
[assembly: ApplicationName("Custom Component")]
[assembly: ApplicationID("[!output GUID_COMPLUS]")]
[assembly: Description("Custom component using C#.NET")]

Not being familiar with COM, I can only assume that either approach
(assigning an AssemblyKeyFile or using the GUID for the applicationID) will
work. I have tried both -- even both at the same time-- but without success.

When I try to run my wizard, I simply get a message box error saying "could
not run the '...' wizard".

My guess is that I have a COM registration problem. My project properties
have RegisterForComInterop = "true" set. The build output window indicates
COM registration is being done. Still, I can't run the wizard.

I have tried running regasm manually, but that doesn't seem to change
anything.

To summarize, here are my questions:
1. To build a COM server in C# that implements the IDTWizard interface, do I
need to sign the assembly with a key pair?
2. Do I need 2 GUIDs (one for the class and one for the ApplicationID)? If
not, which GUIDs do I need?
3. How do I register my C# COM server? (And how can I validate that it is
registered properly?) I assume VS.NET 2003 is doing this automatically, but
if not it seems that running regasm should be good enough...
4. Does it matter which folder I place my dll in? (I am pretty sure it does
not matter, but just checking)
5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?

Thanks!
Mountain
 
Mountain,

See inline:
To summarize, here are my questions:
1. To build a COM server in C# that implements the IDTWizard interface, do I
need to sign the assembly with a key pair?

Yes, if you want to register the assembly for use from COM, it needs to
have a strong name.
2. Do I need 2 GUIDs (one for the class and one for the ApplicationID)? If
not, which GUIDs do I need?

You only need to have the Guid at the class level. Having it on the
assembly level is good practice as well, but at the least, make SURE it is
on the class level.
3. How do I register my C# COM server? (And how can I validate that it is
registered properly?) I assume VS.NET 2003 is doing this automatically, but
if not it seems that running regasm should be good enough...

Yes, running regasm will register the assembly for COM.
4. Does it matter which folder I place my dll in? (I am pretty sure it does
not matter, but just checking)

Yes, it does. When running from COM, it has to be able to find your
assembly. You have two options. You could place the assembly in the GAC,
which means that it will always be found. If your assembly will live in one
directory, then use the /codebase flag when running regasm. This will cause
the path of the assembly to be placed in the registry, so it can be found by
COM (and then by .NET).
5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?

There is not much you can do at this point, because you would have to
have acess to the CLR code, which you do not.

Hope this helps.
 
Thanks for your responses. They are helpful.
However, I am still not able to solve this problem. It is baffling me.

I have reduced everything to the simplest case. I wrote a C# COM server that
implements the IDTWizard interface. My Execute method simply returns
success.

I have GUIDs at the class and assembly level. I am using a strong name. I
registered the dll with regasm /codebase.

Then, I simply took an existing VS.NET wizard and replaced the wizard = line
in the .vsz file with my custom wizard engine (in order to eliminate issues
with folders, .vsdir files, etc. as potential problems).

Now, when I run the wizard, I still get the exact same error:
---------------------------
Microsoft Development Environment
---------------------------
Could not run the 'C:\Program Files\Microsoft Visual Studio .NET
2003\VC#\CSharpProjectItems\LocalProjectItems\Code\..\..\CSharpAddClassWiz.v
sz' wizard.
---------------------------
OK
---------------------------

I hope someone can suggest something that I'm overlooking or doing
incorrectly.
Thanks!


Nicholas Paldino said:
Mountain,

See inline:
To summarize, here are my questions:
1. To build a COM server in C# that implements the IDTWizard interface,
do
I
need to sign the assembly with a key pair?

Yes, if you want to register the assembly for use from COM, it needs to
have a strong name.
2. Do I need 2 GUIDs (one for the class and one for the ApplicationID)? If
not, which GUIDs do I need?

You only need to have the Guid at the class level. Having it on the
assembly level is good practice as well, but at the least, make SURE it is
on the class level.
3. How do I register my C# COM server? (And how can I validate that it is
registered properly?) I assume VS.NET 2003 is doing this automatically, but
if not it seems that running regasm should be good enough...

Yes, running regasm will register the assembly for COM.
4. Does it matter which folder I place my dll in? (I am pretty sure it does
not matter, but just checking)

Yes, it does. When running from COM, it has to be able to find your
assembly. You have two options. You could place the assembly in the GAC,
which means that it will always be found. If your assembly will live in one
directory, then use the /codebase flag when running regasm. This will cause
the path of the assembly to be placed in the registry, so it can be found by
COM (and then by .NET).
5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?

There is not much you can do at this point, because you would have to
have acess to the CLR code, which you do not.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Thanks!
Mountain
 
Is the ProgID attribute required on the class that implements IDTWizard?

For example:
[ProgId("CSharpWizard1")]
public class Builder : IDTWizard

Also, I am seeing more examples of Custom Wizard Engines built as C# COM
Servers that are NOT signed with a key pair and that do not supply a value
in AssemblyKeyFile. For example:

[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

How is it that these COM Servers can be registered without having strong
names?

Regards,

Mountain

Nicholas Paldino said:
Mountain,

See inline:
To summarize, here are my questions:
1. To build a COM server in C# that implements the IDTWizard interface,
do
I
need to sign the assembly with a key pair?

Yes, if you want to register the assembly for use from COM, it needs to
have a strong name.
2. Do I need 2 GUIDs (one for the class and one for the ApplicationID)? If
not, which GUIDs do I need?

You only need to have the Guid at the class level. Having it on the
assembly level is good practice as well, but at the least, make SURE it is
on the class level.
3. How do I register my C# COM server? (And how can I validate that it is
registered properly?) I assume VS.NET 2003 is doing this automatically, but
if not it seems that running regasm should be good enough...

Yes, running regasm will register the assembly for COM.
4. Does it matter which folder I place my dll in? (I am pretty sure it does
not matter, but just checking)

Yes, it does. When running from COM, it has to be able to find your
assembly. You have two options. You could place the assembly in the GAC,
which means that it will always be found. If your assembly will live in one
directory, then use the /codebase flag when running regasm. This will cause
the path of the assembly to be placed in the registry, so it can be found by
COM (and then by .NET).
5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?

There is not much you can do at this point, because you would have to
have acess to the CLR code, which you do not.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Thanks!
Mountain
 
For anyone who is interested, it looks like I found my answer. Adding the
ProgId attribute DID solve this problem. I no longer get the "Could not run
the ... wizard" error.

I wonder why no doc mentions this? Anyway, on to the next problem...

Mr. Mountain said:
Is the ProgID attribute required on the class that implements IDTWizard?

For example:
[ProgId("CSharpWizard1")]
public class Builder : IDTWizard

Also, I am seeing more examples of Custom Wizard Engines built as C# COM
Servers that are NOT signed with a key pair and that do not supply a value
in AssemblyKeyFile. For example:

[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

How is it that these COM Servers can be registered without having strong
names?

Regards,

Mountain

message news:%[email protected]...
Mountain,

See inline:
interface,
do

Yes, if you want to register the assembly for use from COM, it needs to
have a strong name.
ApplicationID)?
If

You only need to have the Guid at the class level. Having it on the
assembly level is good practice as well, but at the least, make SURE it is
on the class level.
automatically,
but

Yes, running regasm will register the assembly for COM.


Yes, it does. When running from COM, it has to be able to find your
assembly. You have two options. You could place the assembly in the GAC,
which means that it will always be found. If your assembly will live in one
directory, then use the /codebase flag when running regasm. This will cause
the path of the assembly to be placed in the registry, so it can be
found
by
COM (and then by .NET).
5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?

There is not much you can do at this point, because you would have to
have acess to the CLR code, which you do not.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Thanks!
Mountain
 
I am not a COM expert. However, after seeing some example of Custom Wizard
Engines developed as C# COM Servers that did NOT have strong names, I tested
this myself. (I was finally able to test this because I solved my earlier
problems by using the ProgId attribute, as described in another post.)

I found out that a strong name is *not* required. I do not know why there is
so much conflicting info on this, so I am just relating my experience.

As a summary, here are my own answers to my original 5 questions. These are
based on my own testing, and they conflict with what others have stated. I
can only share my experience. Hopefully someone will step in and provide a
deeper explanation about the conflicting info.


1. To build a COM server in C# that implements the IDTWizard interface, do I
need to sign the assembly with a key pair?
NO!

2. Do I need 2 GUIDs (one for the class and one for the ApplicationID)? If
not, which GUIDs do I need?
Prior response from Nicholas Paldino seems correct. I haven't found any
additional info.

3. How do I register my C# COM server? (And how can I validate that it is
registered properly?) I assume VS.NET 2003 is doing this automatically, but
if not it seems that running regasm should be good enough...
VS.NET does this automatically if the project properties have
RegisterForComInterop = "true" set. Manually running regasm is NOT required.
I tested this by running regasm to unregister my dll, then building and
testing my custom wizard engine without manually running regasm.

4. Does it matter which folder I place my dll in? (I am pretty sure it does
not matter, but just checking)
NO. I left it in \bin\Debug under my project. It was referenced from a .vsz
file in the default VS.NET install folder (on another drive).

5. Given that I seem to be getting failure before my dll is found, my
breakpoints are never hit. What would be the appropriate debugging technique
at the stage where I'm having problems?
Prior response from Nicholas Paldino seems correct. I haven't found any
additional info.
 
Hi,
I'm not an expert also, as Nicholas is, but:

I am not a COM expert. However, after seeing some example of Custom Wizard
Engines developed as C# COM Servers that did NOT have strong names, I tested
this myself. (I was finally able to test this because I solved my earlier
problems by using the ProgId attribute, as described in another post.)

I found out that a strong name is *not* required. I do not know why there is
so much conflicting info on this, so I am just relating my experience.

This is not required, i.e. you can install it, but ... what will happen
if someone else installs/has an assembly with the same name. Which one
will CLR load? This is very importatnt for addins, as all the addins are
imported in the same appdomain, and if there is already an assembly with
the same name, the loading will fail. That's why strong naming is highly
recommended. You can not control what users do install on their
machines, so there is a possible conflict.

Actually just few days ago I have discovered that point of view, so now
I'm going thru the process of strongly naming whole my COM interop
solution :). Thats very good that I have found it just before deployment
:)

Sunny
 
Good points. I should have mentioned that I am building this custom wizard
engine for my own use only on my development machine.

I'm also trying to find the most basic configuration possible, so I can
understand which settings are always optional, which are sometimes optional,
and which are always required under all circumstances.

Regards,
Mountain
 

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

Back
Top