gpt4 book ai didi

c# - 如何部署 visual studio 自定义工具?

转载 作者:太空狗 更新时间:2023-10-29 21:15:30 24 4
gpt4 key购买 nike

我有自己的 Visual Studio 2008 SP1 自定义工具。它由 5 个程序集组成:3 个包含我的其他项目中大量使用的代码的程序集,1 个 VS2008 SDK 之上的程序集包装器和一个带有该工具的程序集。

如果我从 visual studio 调试我的工具,使用“运行外部程序”选项和命令行“C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe”和参数“/ranu/rootsuffix Exp"一切正常。

之后,我尝试将它部署到我的工作 VS 副本,而不是实验性配置单元,对我的所有程序集执行:gacutil/i Asm1.dll 并执行 RegAsm Asm1。 dll 仅用于使用自定义工具进行组装。两个 utils 都没有打印任何错误,一切都按计划工作,甚至出现了注册表项。但是即使在 PC 重新启动后,我的工具也不起作用(发生错误“在此系统上找不到自定义工具‘TransportGeneratorTool’”)。我做错了什么?

包装器看起来像这样:

[ComVisible(true)]
public abstract class CustomToolBase : IVsSingleFileGenerator, IObjectWithSite
{
#region IVsSingleFileGenerator Members
int IVsSingleFileGenerator.DefaultExtension(out string pbstrDefaultExtension)
{
pbstrDefaultExtension = ".cs";
return 0;
}

int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
{
GenerationEventArgs gea = new GenerationEventArgs(
bstrInputFileContents,
wszInputFilePath,
wszDefaultNamespace,
new ServiceProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider)
.GetService(typeof(ProjectItem)) as ProjectItem,
new GenerationProgressFacade(pGenerateProgress)
);

if (OnGenerateCode != null)
{
OnGenerateCode(this, gea);
}

byte[] bytes = gea.GetOutputCodeBytes();

int outputLength = bytes.Length;
rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
pcbOutput = (uint)outputLength;
return VSConstants.S_OK;
}
#endregion

#region IObjectWithSite Members
void IObjectWithSite.GetSite(ref Guid riid, out IntPtr ppvSite)
{
IntPtr pUnk = Marshal.GetIUnknownForObject(Site);
IntPtr intPointer = IntPtr.Zero;
Marshal.QueryInterface(pUnk, ref riid, out intPointer);
ppvSite = intPointer;
}

void IObjectWithSite.SetSite(object pUnkSite)
{
Site = pUnkSite;
}
#endregion

#region Public Members
public object Site { get; private set; }

public event EventHandler<GenerationEventArgs> OnGenerateCode;

[ComRegisterFunction]
public static void Register(Type type)
{
using (var parent = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\VisualStudio\9.0", true))
foreach (CustomToolRegistrationAttribute ourData in type.GetCustomAttributes(typeof(CustomToolRegistrationAttribute), false))
ourData.Register(x => parent.CreateSubKey(x), (x, name, value) => x.SetValue(name, value));
}

[ComUnregisterFunction]
public static void Unregister(Type type)
{
using (var parent = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\VisualStudio\9.0", true))
foreach (CustomToolRegistrationAttribute ourData in type.GetCustomAttributes(typeof(CustomToolRegistrationAttribute), false))
ourData.Unregister(x => parent.DeleteSubKey(x, false));
}

#endregion
}

我的工具代码:

[ComVisible(true)]
[Guid("55A6C192-D29F-4e22-84DA-DBAF314ED5C3")]
[CustomToolRegistration(ToolName, typeof(TransportGeneratorTool))]
[ProvideObject(typeof(TransportGeneratorTool))]
public class TransportGeneratorTool : CustomToolBase
{
private const string ToolName = "TransportGeneratorTool";

public TransportGeneratorTool()
{
OnGenerateCode += GenerateCode;
}

private static void GenerateCode(object s, GenerationEventArgs e)
{
try
{
var serializer = new XmlSerializer(typeof (Parser.System));
using (var reader = new StringReader(e.InputText))
using (var writer = new StringWriter(e.OutputCode))
{
Generator.System = (Parser.System) serializer.Deserialize(reader);
Generator.System.Namespace = e.Namespace;
Generator.GenerateSource(writer);
}
}
catch (Exception ex)
{
e.Progress.GenerateError(ex.ToString());
}
}
}

生成的注册表项:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\TransportGeneratorTool]
@="TransportGeneratorTool"
"CLSID"="{55a6c192-d29f-4e22-84da-dbaf314ed5c3}"
"GeneratesDesignTimeSource"=dword:00000001
"GeneratesSharedDesignTimeSource"=dword:00000001

这是我的自定义属性的代码(它在包装器程序集中):

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class CustomToolRegistrationAttribute : RegistrationAttribute
{
public CustomToolRegistrationAttribute(string name, Type customToolType)
{
Name = name;
CustomToolType = customToolType;
}

/// <summary>
/// The type that implements the custom tool. This starts
/// as MyCustomTool by default in the template.
/// </summary>
public Type CustomToolType { get; set; }

public string Name { get; set; }

#region RegistrationAttribute abstract member implementations
public override void Register(RegistrationContext context)
{
Register(x => context.CreateKey(x), (x, key, value) => x.SetValue(key, value));
}

public void Register<T>(Func<string, T> keyCreator, Action<T, string, object> valueCreator)
{
var keyName = CreateKeyName(Name);
var key = keyCreator(keyName);

valueCreator(key, string.Empty, Name);
valueCreator(key, "CLSID", CustomToolType.GUID.ToString("B"));
valueCreator(key, "GeneratesDesignTimeSource", 1);
valueCreator(key, "GeneratesSharedDesignTimeSource", 1);

var disposable = key as IDisposable;
if (disposable != null)
disposable.Dispose();
}

private static string CreateKeyName(string name)
{
return string.Format(@"Generators\{0}\{1}", vsContextGuids.vsContextGuidVCSProject, name);
}

public override void Unregister(RegistrationContext context)
{
Unregister(context.RemoveKey);
}

public void Unregister(Action<string> keyRemover)
{
keyRemover(CreateKeyName(Name));
}

#endregion
}

最佳答案

我的解决方案是制作一个安装项目。我通过将以下内容添加到程序包的 csproj 文件来从 pkgdef 文件获取注册表设置:

<Target Name="GeneratePackageRegistryFiles">
<Exec Command="&quot;$(VSSDK90Install)VisualStudioIntegration\Tools\Bin\RegPkg.exe&quot; /root:Software\Microsoft\VisualStudio\9.0 /codebase &quot;$(TargetPath)&quot; /regfile:&quot;$(OutDir)$(TargetName).reg&quot;" />
</Target>
<PropertyGroup>
<BuildDependsOn>$(BuildDependsOn);GeneratePackageRegistryFiles;</BuildDependsOn>
</PropertyGroup>

在输出目录中构建外观时,您应该找到一个可以在安装项目中导入的 .reg 文件。

显然,如果无法修改项目,您可以从命令行运行 regpkg.exe。

关于c# - 如何部署 visual studio 自定义工具?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2583760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com