Visual studio 2013 如何使VSIX安装程序自动注册程序集
我开发了一个自定义代码生成器,并通过VSIX进行部署,问题是在安装VSIX后,我应该通过regasm.exe注册程序集,但我见过一些项目,例如具有自动注册的自定义代码生成的DSLTool,任何人都知道如何在我的VSIX项目中自动注册?您应该能够执行以下操作: 0删除旧的(不良做法)COM代码Visual studio 2013 如何使VSIX安装程序自动注册程序集,visual-studio-2013,vsix,regasm,Visual Studio 2013,Vsix,Regasm,我开发了一个自定义代码生成器,并通过VSIX进行部署,问题是在安装VSIX后,我应该通过regasm.exe注册程序集,但我见过一些项目,例如具有自动注册的自定义代码生成的DSLTool,任何人都知道如何在我的VSIX项目中自动注册?您应该能够执行以下操作: 0删除旧的(不良做法)COM代码 编辑项目生成设置,使其不选中“注册COM互操作” 编辑您的AssemblyInfo.cs并将ComVisible设置为false: [assembly: ComVisible(false)] 假设您的生
ComVisible
设置为false
:
[assembly: ComVisible(false)]
MyCodeGenerator
,请打开MyCodeGenerator
的定义并添加属性:
[ComVisible(true)]
true
元素的末尾,该元素没有条件
属性(这几乎总是文件中的第一个属性组
)
如果扩展不提供任何其他内容元素,则整个
元素现在将是:
<Content>
<VsPackage>|%CurrentProject%|</VsPackage>
</Content>
MyCodeGenerator
,并且您希望向C#language服务注册代码生成器,请将以下属性添加到程序集信息文件中
[assembly: ProvideAssemblyObject(typeof(MyCodeGenerator))]
[assembly: ProvideGenerator(
typeof(MyCodeGenerator),
VSConstants.UICONTEXT.CSharpProject_string,
Description = "Description of the generator",
GeneratesDesignTimeSource = true)]
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideGeneratorAttribute : RegistrationAttribute
{
private readonly Type _generatorType;
private readonly Guid _languageServiceGuid;
private string _name;
private string _description;
private bool _generatesDesignTimeSource;
public ProvideGeneratorAttribute(Type generatorType, string languageServiceGuid)
{
if (generatorType == null)
throw new ArgumentNullException("generatorType");
if (languageServiceGuid == null)
throw new ArgumentNullException("languageServiceGuid");
if (string.IsNullOrEmpty(languageServiceGuid))
throw new ArgumentException("languageServiceGuid cannot be empty");
_generatorType = generatorType;
_languageServiceGuid = new Guid(languageServiceGuid);
_name = _generatorType.Name;
}
public Type GeneratorType
{
get
{
return _generatorType;
}
}
public Guid LanguageServiceGuid
{
get
{
return _languageServiceGuid;
}
}
public string Name
{
get
{
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (string.IsNullOrEmpty(value))
throw new ArgumentException("value cannot be empty");
_name = value;
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
public bool GeneratesDesignTimeSource
{
get
{
return _generatesDesignTimeSource;
}
set
{
_generatesDesignTimeSource = value;
}
}
private string RegistrationKey
{
get
{
return string.Format(@"Generators\{0}\{1}", LanguageServiceGuid.ToString("B"), Name);
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(RegistrationKey))
{
if (!string.IsNullOrEmpty(Description))
key.SetValue(string.Empty, Description);
key.SetValue("CLSID", GeneratorType.GUID.ToString("B"));
key.SetValue("GeneratesDesignTimeSource", GeneratesDesignTimeSource ? 1 : 0);
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(RegistrationKey);
}
}
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideAssemblyObjectAttribute : RegistrationAttribute
{
private readonly Type _objectType;
private RegistrationMethod _registrationMethod;
public ProvideAssemblyObjectAttribute(Type objectType)
{
if (objectType == null)
throw new ArgumentNullException("objectType");
_objectType = objectType;
}
public Type ObjectType
{
get
{
return _objectType;
}
}
public RegistrationMethod RegistrationMethod
{
get
{
return _registrationMethod;
}
set
{
_registrationMethod = value;
}
}
private string ClsidRegKey
{
get
{
return string.Format(@"CLSID\{0}", ObjectType.GUID.ToString("B"));
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(ClsidRegKey))
{
key.SetValue(string.Empty, ObjectType.FullName);
key.SetValue("InprocServer32", context.InprocServerPath);
key.SetValue("Class", ObjectType.FullName);
if (context.RegistrationMethod != RegistrationMethod.Default)
_registrationMethod = context.RegistrationMethod;
switch (RegistrationMethod)
{
case Microsoft.VisualStudio.Shell.RegistrationMethod.Default:
case Microsoft.VisualStudio.Shell.RegistrationMethod.Assembly:
key.SetValue("Assembly", ObjectType.Assembly.FullName);
break;
case Microsoft.VisualStudio.Shell.RegistrationMethod.CodeBase:
key.SetValue("CodeBase", context.CodeBase);
break;
default:
throw new InvalidOperationException();
}
key.SetValue("ThreadingModel", "Both");
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(ClsidRegKey);
}
}
附录B:ProvideAssemblyObjectAttribute.cs
免责声明:此代码完全未经测试。
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideGeneratorAttribute : RegistrationAttribute
{
private readonly Type _generatorType;
private readonly Guid _languageServiceGuid;
private string _name;
private string _description;
private bool _generatesDesignTimeSource;
public ProvideGeneratorAttribute(Type generatorType, string languageServiceGuid)
{
if (generatorType == null)
throw new ArgumentNullException("generatorType");
if (languageServiceGuid == null)
throw new ArgumentNullException("languageServiceGuid");
if (string.IsNullOrEmpty(languageServiceGuid))
throw new ArgumentException("languageServiceGuid cannot be empty");
_generatorType = generatorType;
_languageServiceGuid = new Guid(languageServiceGuid);
_name = _generatorType.Name;
}
public Type GeneratorType
{
get
{
return _generatorType;
}
}
public Guid LanguageServiceGuid
{
get
{
return _languageServiceGuid;
}
}
public string Name
{
get
{
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (string.IsNullOrEmpty(value))
throw new ArgumentException("value cannot be empty");
_name = value;
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
public bool GeneratesDesignTimeSource
{
get
{
return _generatesDesignTimeSource;
}
set
{
_generatesDesignTimeSource = value;
}
}
private string RegistrationKey
{
get
{
return string.Format(@"Generators\{0}\{1}", LanguageServiceGuid.ToString("B"), Name);
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(RegistrationKey))
{
if (!string.IsNullOrEmpty(Description))
key.SetValue(string.Empty, Description);
key.SetValue("CLSID", GeneratorType.GUID.ToString("B"));
key.SetValue("GeneratesDesignTimeSource", GeneratesDesignTimeSource ? 1 : 0);
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(RegistrationKey);
}
}
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideAssemblyObjectAttribute : RegistrationAttribute
{
private readonly Type _objectType;
private RegistrationMethod _registrationMethod;
public ProvideAssemblyObjectAttribute(Type objectType)
{
if (objectType == null)
throw new ArgumentNullException("objectType");
_objectType = objectType;
}
public Type ObjectType
{
get
{
return _objectType;
}
}
public RegistrationMethod RegistrationMethod
{
get
{
return _registrationMethod;
}
set
{
_registrationMethod = value;
}
}
private string ClsidRegKey
{
get
{
return string.Format(@"CLSID\{0}", ObjectType.GUID.ToString("B"));
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(ClsidRegKey))
{
key.SetValue(string.Empty, ObjectType.FullName);
key.SetValue("InprocServer32", context.InprocServerPath);
key.SetValue("Class", ObjectType.FullName);
if (context.RegistrationMethod != RegistrationMethod.Default)
_registrationMethod = context.RegistrationMethod;
switch (RegistrationMethod)
{
case Microsoft.VisualStudio.Shell.RegistrationMethod.Default:
case Microsoft.VisualStudio.Shell.RegistrationMethod.Assembly:
key.SetValue("Assembly", ObjectType.Assembly.FullName);
break;
case Microsoft.VisualStudio.Shell.RegistrationMethod.CodeBase:
key.SetValue("CodeBase", context.CodeBase);
break;
default:
throw new InvalidOperationException();
}
key.SetValue("ThreadingModel", "Both");
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(ClsidRegKey);
}
}
我在“项目属性”窗口的“构建”选项卡中找到了“注册COM互操作”选项,似乎这就是解决方案,但在设置之后,我得到了这个错误错误3未为COM互操作注册程序集“Microsoft.VisualStudio.Shell.Interop,版本=7.1.40304.0,区域性=中性,PublicKeyToken=b03f5f7f11d50a3a”。请使用regasm.exe/tlb.dsl包注册“我编辑了我的答案,以确保删除此生成设置以及其他不再需要的COM相关元素。非常感谢,它可以工作,但我使用了内置的ProvideGeneratorAttribute,而不是VS2019上内置的ProvideGeneratorAttribute和ProvideGeneratorAttribute-“在此系统上找不到自定义工具XYZ”;对于ComVisible的使用方式,它不起作用。我想它确实需要regasm注册。。。