1 //------------------------------------------------------------------------------
2 // <copyright file="ProvideEditorExtensionAttribute.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace Microsoft
.VisualStudio
.Shell
{
11 using System
.Globalization
;
14 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute"]' />
16 /// This attribute associates a file extension to a given editor factory.
17 /// The editor factory may be specified as either a GUID or a type and
18 /// is placed on a package.
20 [AttributeUsage(AttributeTargets
.Class
, AllowMultiple
=true, Inherited
=true)]
21 public sealed class ProvideEditorExtensionAttribute
: RegistrationAttribute
{
24 private string extension
;
27 private string templateDir
;
29 private bool editorFactoryNotify
;
30 private string editorName
;
32 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.ProvideEditorExtensionAttribute"]' />
34 /// Creates a new attribute.
36 public ProvideEditorExtensionAttribute (object factoryType
, string extension
, int priority
) {
38 if (!extension
.StartsWith(".", StringComparison
.OrdinalIgnoreCase
)) {
39 throw new ArgumentException(SR
.GetString(SR
.Attributes_ExtensionNeedsDot
, extension
));
42 // figure out what type of object they passed in and get the GUID from it
43 if (factoryType
is string)
44 this.factory
= new Guid((string)factoryType
);
45 else if (factoryType
is Type
)
46 this.factory
= ((Type
)factoryType
).GUID
;
47 else if (factoryType
is Guid
)
48 this.factory
= (Guid
)factoryType
;
50 throw new ArgumentException(SR
.GetString(SR
.Attributes_InvalidFactoryType
, factoryType
));
52 this.extension
= extension
;
53 this.priority
= priority
;
54 this.project
= Guid
.Empty
;
55 this.templateDir
= "";
57 this.editorFactoryNotify
= false;
60 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.Extension"]' />
62 /// The file extension of the file.
64 public string Extension
{
70 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.Factory"]' />
72 /// The editor factory guid.
80 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.Priority"]' />
82 /// The priority of this extension registration.
90 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.ProjectGuid"]/*' />
91 public string ProjectGuid
{
92 set { project = new System.Guid(value); }
93 get { return project.ToString(); }
96 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.EditorFactoryNotify"]/*' />
97 public bool EditorFactoryNotify
{
98 get { return this.editorFactoryNotify; }
99 set { this.editorFactoryNotify = value; }
102 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.TemplateDir"]/*' />
103 public string TemplateDir
{
104 get { return templateDir; }
105 set { templateDir = value; }
108 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.NameResourceID"]/*' />
109 public int NameResourceID
{
110 get { return resId; }
111 set { resId = value; }
114 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="ProvideEditorExtensionAttribute.DefaultName"]/*' />
115 public string DefaultName
{
116 get { return editorName; }
117 set { editorName = value; }
121 /// The reg key name of this extension.
123 private string RegKeyName
127 return string.Format(CultureInfo
.InvariantCulture
, "Editors\\{0}", Factory
.ToString("B"));
132 /// The reg key name of the project.
134 private string ProjectRegKeyName(RegistrationContext context
)
136 return string.Format(CultureInfo
.InvariantCulture
,
137 "Projects\\{0}\\AddItemTemplates\\TemplateDirs\\{1}",
138 project
.ToString("B"),
139 context
.ComponentType
.GUID
.ToString("B"));
142 private string EditorFactoryNotifyKey
{
143 get { return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}
\\FileExtensions
\\{1}
",
144 project.ToString("B
"),
149 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="Register
"]' />
151 /// Called to register this attribute with the given context. The context
152 /// contains the location where the registration inforomation should be placed.
153 /// it also contains such as the type being registered, and path information.
155 /// This method is called both for registration and unregistration. The difference is
156 /// that unregistering just uses a hive that reverses the changes applied to it.
158 public override void Register(RegistrationContext context) {
159 context.Log.WriteLine(SR.GetString(SR.Reg_NotifyEditorExtension, Extension, Factory.ToString("B
")));
161 using (Key editorKey = context.CreateKey(RegKeyName))
163 if (!string.IsNullOrEmpty(DefaultName))
165 editorKey.SetValue(null, DefaultName);
168 editorKey.SetValue("DisplayName
", "#" + resId.ToString(CultureInfo.InvariantCulture));
169 editorKey.SetValue("Package", context.ComponentType.GUID.ToString("B"));
172 using (Key extensionKey = context.CreateKey(RegKeyName + "\\Extensions"))
174 extensionKey.SetValue(Extension.Substring(1), Priority);
177 // Build the path of the registry key for the "Add file to project" entry
178 if (project != Guid.Empty)
180 string prjRegKey = ProjectRegKeyName(context) + "\\/1";
181 using (Key projectKey = context.CreateKey( prjRegKey ))
184 projectKey.SetValue("", "#" + resId.ToString(CultureInfo.InvariantCulture));
185 if (templateDir.Length != 0)
187 Uri url = new Uri(context.ComponentType.Assembly.CodeBase, true);
188 string templates = url.LocalPath;
189 templates = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(templates), templateDir);
190 templates = context.EscapePath( System.IO.Path.GetFullPath(templates) );
191 projectKey.SetValue("TemplatesDir", templates);
193 projectKey.SetValue("SortPriority", Priority);
197 // Register the EditorFactoryNotify
198 if ( EditorFactoryNotify )
200 // The IVsEditorFactoryNotify interface is called by the project system, so it doesn't make sense to
201 // register it if there is no project associated to this editor.
202 if (project == Guid.Empty)
203 throw new ArgumentException(SR.GetString(SR.Attributes_NoPrjForEditorFactoryNotify));
205 // Create the registry key
206 using (Key edtFactoryNotifyKey = context.CreateKey(EditorFactoryNotifyKey))
208 edtFactoryNotifyKey.SetValue("EditorFactoryNotify", Factory.ToString("B"));
213 /// <include file='doc\ProvideEditorExtensionAttribute.uex' path='docs/doc[@for="Unregister"]' />
215 /// Unregister this editor.
217 /// <param name="context"></param>
218 public override void Unregister(RegistrationContext context)
220 context.RemoveKey(RegKeyName);
221 if (project != Guid.Empty)
223 context.RemoveKey(ProjectRegKeyName(context));
224 if (EditorFactoryNotify)
225 context.RemoveKey(EditorFactoryNotifyKey);