Installer classes and extending them

R

Roy Chastain

The documentation on ServiceInstaller.CopyFromComponent says

Note If you are using the Visual Studio designer, this method is called at design time when the user clicks Add Installer on a
component that specified this class as its installer. The installer takes all information it can from the live component and
stores it for use at install time.

Note that the words are different or missing in each of the other classes that derive from ComponentInstaller.

Question 1
"component that specified this class as its installer" - How does a component specify a class as its installer?

Question 2
How do I make a class that derives from ComponentInstaller designable such that it can be dragged into a project like
ServiceInstaller and the other classes that are derived from ComponentInstaller?
 
J

Jeffrey Tan[MSFT]

Hi Roy,

Thanks for your post.

I will answer your questions one by one:
#1, Normally, ServiceBase class has the "Add Installer" link in the
PropertyBrowser at design-time. Actually, this link is called
designer-verb, which is added to ServiceBase by a customized designer.

If we use Reflector to view ServiceBase, we will get:
[Designer("Microsoft.VisualStudio.Install.UserNTServiceDesigner,
Microsoft.VisualStudio, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a",
"System.ComponentModel.Design.IRootDesigner"),
public class ServiceBase : Component

Yes, it is this UserNTServiceDesigner which added this design-verb. This
class resided in Microsoft.VisualStudio.dll. We can first add "D:\Program
Files\Microsoft Visual Studio .NET
2003\Common7\IDE\Microsoft.VisualStudio.dll" into Reflector, then view
UserNTServiceDesigner.Verbs property. I get this:
public override DesignerVerbCollection Verbs
{
get
{
if (this.verbs == null)
{
this.verbs = new DesignerVerbCollection();
this.verbs.Add(new
DesignerVerb(SR.GetString("InstallerDesign_AddInstallerLink"), new
EventHandler(this.OnAddInstallerVerb)));
}
return this.verbs;
}
}

Yes, all the work is done in UserNTServiceDesigner.OnAddInstallerVerb
method, we can view it:
private void OnAddInstallerVerb(object sender, EventArgs e)
{
IComponent component1 = base.Component;
IDesignerHost host1 =
InstallerDesign.GetProjectInstallerDocument(component1);
ServiceInstaller installer1 = new ServiceInstaller();
installer1.CopyFromComponent(component1);
IContainer container1 = host1.Container;
ComponentCollection collection1 = container1.Components;
ServiceProcessInstaller installer2 = null;
foreach (IComponent component2 in collection1)
{
ServiceInstaller installer3 = component2 as ServiceInstaller;
if ((installer3 != null) &&
installer1.IsEquivalentInstaller(installer3))
{
InstallerDesign.SelectComponent(installer3);
return;
}
}
foreach (IComponent component3 in collection1)
{
if (component3 is ServiceProcessInstaller)
{
installer2 = (ServiceProcessInstaller) component3;
break;
}
}
if (installer2 == null)
{
installer2 = new ServiceProcessInstaller();
container1.Add(installer2);
}
container1.Add(installer1);
InstallerDesign.SelectComponent(installer1);
}
You can proceed to view InstallerDesign.GetProjectInstallerDocument()
etc... in Reflector.

I hope this makes sense to you.

#2, any class inherited from Component class can be designable. And when it
is dropped on the VS.net designer, it will appear in the component tray
just below the designer. Because ComponentInstaller inherited from
Component class like this:
System.ComponentModel.Component
System.Configuration.Install.Installer
System.Configuration.Install.ComponentInstaller

So any classes derived from ComponentInstaller will be designable.

Hope this hellps. Thanks
==================================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
R

Roy Chastain

Thanks for reminding me about Custom Designers. (I think I keep forgetting about them on purpose.)

As for making something that derives from ComponentInstaller designable, I am running into a problem. I thought that it should
just work, but it is not.

I have
public class CASPolicyInstaller: System.Configuration.Install.ComponentInstaller
{
.... code including
public override void CopyFromComponent (System.ComponentModel.IComponent component)
{
} /* method CASPolicyInstaller CopyFromComponent */
}

I have the following problem when I double click the .CS file that contains the code above, I get an error telling me,
"The designer must create an instance of System.Configuration.Install.ComponentInstaller but it cannot because the type is
declared as abstract".

I am probably missing something very basic here, but I don't know what.


Hi Roy,

Thanks for your post.

I will answer your questions one by one:
#1, Normally, ServiceBase class has the "Add Installer" link in the
PropertyBrowser at design-time. Actually, this link is called
designer-verb, which is added to ServiceBase by a customized designer.

If we use Reflector to view ServiceBase, we will get:
[Designer("Microsoft.VisualStudio.Install.UserNTServiceDesigner,
Microsoft.VisualStudio, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a",
"System.ComponentModel.Design.IRootDesigner"),
public class ServiceBase : Component

Yes, it is this UserNTServiceDesigner which added this design-verb. This
class resided in Microsoft.VisualStudio.dll. We can first add "D:\Program
Files\Microsoft Visual Studio .NET
2003\Common7\IDE\Microsoft.VisualStudio.dll" into Reflector, then view
UserNTServiceDesigner.Verbs property. I get this:
public override DesignerVerbCollection Verbs
{
get
{
if (this.verbs == null)
{
this.verbs = new DesignerVerbCollection();
this.verbs.Add(new
DesignerVerb(SR.GetString("InstallerDesign_AddInstallerLink"), new
EventHandler(this.OnAddInstallerVerb)));
}
return this.verbs;
}
}

Yes, all the work is done in UserNTServiceDesigner.OnAddInstallerVerb
method, we can view it:
private void OnAddInstallerVerb(object sender, EventArgs e)
{
IComponent component1 = base.Component;
IDesignerHost host1 =
InstallerDesign.GetProjectInstallerDocument(component1);
ServiceInstaller installer1 = new ServiceInstaller();
installer1.CopyFromComponent(component1);
IContainer container1 = host1.Container;
ComponentCollection collection1 = container1.Components;
ServiceProcessInstaller installer2 = null;
foreach (IComponent component2 in collection1)
{
ServiceInstaller installer3 = component2 as ServiceInstaller;
if ((installer3 != null) &&
installer1.IsEquivalentInstaller(installer3))
{
InstallerDesign.SelectComponent(installer3);
return;
}
}
foreach (IComponent component3 in collection1)
{
if (component3 is ServiceProcessInstaller)
{
installer2 = (ServiceProcessInstaller) component3;
break;
}
}
if (installer2 == null)
{
installer2 = new ServiceProcessInstaller();
container1.Add(installer2);
}
container1.Add(installer1);
InstallerDesign.SelectComponent(installer1);
}
You can proceed to view InstallerDesign.GetProjectInstallerDocument()
etc... in Reflector.

I hope this makes sense to you.

#2, any class inherited from Component class can be designable. And when it
is dropped on the VS.net designer, it will appear in the component tray
just below the designer. Because ComponentInstaller inherited from
Component class like this:
System.ComponentModel.Component
System.Configuration.Install.Installer
System.Configuration.Install.ComponentInstaller

So any classes derived from ComponentInstaller will be designable.

Hope this hellps. Thanks
==================================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Roy,

Thanks for your feedback.

Yes, because ComponentInstaller is an abstract class, it can not be
initialized. Only its child class instance can be initialized, and this
child class(your CASPolicyInstaller) must override and implement its
abstract method: CopyFromComponent. However your CASPolicyInstaller did not
implement this method, so an compile time error gerenated.

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

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