2010-04-06 16 views
6

मेरे पास विजुअल स्टूडियो 2008 एसपी 1 के लिए मेरा अपना कस्टम टूल है। इसमें 5 असेंबली होती हैं: कोड के साथ 3 असेंबली जो मेरी अन्य परियोजनाओं में भारी मात्रा में उपयोग की जाती हैं, वीएस -2008 एसडीके के ऊपर 1 असेंबली-रैपर और उपकरण के साथ एक असेंबली।दृश्य स्टूडियो कस्टम टूल को कैसे तैनात किया जाए?

यदि मैं कमांड लाइन "सी: \ प्रोग्राम फ़ाइलें (x86) \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ devenv.exe" और तर्कों के साथ "बाहरी प्रोग्राम चलाएं" विकल्प का उपयोग करके दृश्य स्टूडियो से अपना टूल डीबग कर दूंगा "/ ranu/rootuffix एक्सप" सभी पूरी तरह से काम करता है।

उसके बाद मैं अपने कामकाजी वीएस प्रतिलिपि पर तैनात करने की कोशिश कर रहा हूं, प्रयोगात्मक छिद्र के लिए नहीं: gacutil /i Asm1.dll मेरी सभी असेंबली के लिए और RegAsm Asm1.dll केवल कस्टम टूल के साथ असेंबली के लिए कर रहा हूं। न तो किसी भी त्रुटि को प्रिंट करता है, योजना के अनुसार सभी काम करते हैं, यहां तक ​​कि रजिस्ट्री कुंजियां भी दिखाई देती हैं। लेकिन मेरा उपकरण काम नहीं करता है (त्रुटि हुई "पीसी को पुनरारंभ करने के बाद भी" इस उपकरण पर कस्टम उपकरण '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 
} 
+0

कृपया "काम नहीं करता" का विस्तार करें: क्या आपको कोई त्रुटि मिल रही है, या ऐसा है जैसे इसे कभी इंस्टॉल नहीं किया गया था? – Richard

+0

जैसा कि यह कभी स्थापित नहीं किया गया था। –

+0

मैंने –

उत्तर

6

मेरा समाधान एक सेटअप प्रोजेक्ट बनाना है।

<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 फ़ाइल जो आपको सेटअप परियोजना में आयात कर सकते हैं खोजने चाहिए: मैं पैकेज के csproj फ़ाइल में निम्न जोड़कर pkgdef फ़ाइल से रजिस्ट्री सेटिंग्स मिल ।

स्पष्ट रूप से आप प्रोजेक्ट को संशोधित करने का विकल्प नहीं है, तो आप कमांड लाइन से regpkg.exe चला सकते हैं।

+0

बहुत बहुत धन्यवाद। RegPkg मुझे बचाओ :) –

+0

एरर, मैं आपका जवाब स्वीकार करने के लिए क्लिक कर रहा हूं, लेकिन यह मुझे यह दिखाता है: http://img706.imageshack.us/img706/761/bounty.png मुझे क्या करना चाहिए? –

+0

जैसा कि मैं इसे समझता हूं, आपको एक और घंटे का इंतजार करना चाहिए। – ErvinS

4

यही वह समय है जब मैंने अपना कस्टम टूल पंजीकृत करने के लिए संघर्ष किया था। मुझे आशा है कि यह निर्देश पर्याप्त विस्तृत है और सब कुछ शामिल है ताकि आप इसे लड़ने में ज्यादा समय नहीं लगा सकें। निम्नलिखित एमएसडीएन आलेख को प्रारंभिक बिंदु के रूप में उपयोग किया गया था। http://msdn.microsoft.com/en-US/library/bb166527(v=vs.80).aspx दुर्भाग्य से आप इसे अकेले उपयोग नहीं कर सकते हैं। आपको वास्तव में क्या करना है:

  1. सुनिश्चित करें कि असेंबली पर हस्ताक्षर किए गए हैं। क्यूं कर? क्योंकि अन्यथा आप इसे नीचे चरण 6 पर जीएसी में नहीं डाल पाएंगे। अपनी असेंबली पर हस्ताक्षर करने के लिए इन चरणों का पालन करें:

    1.1। प्रोजेक्ट की गुण स्क्रीन पर जाएं।

    1.2। एक बार पर जाएं टैब पर हस्ताक्षर करें।

    1.3। एक बार वहां जांचें असेंबली चेकबॉक्स पर हस्ताक्षर करें।

  2. सुनिश्चित करें कि आप अपनी असेंबली का संस्करण संख्या जानते हैं।आपको ASSEMBLY_VERSION पैरामीटर बाद में निर्दिष्ट करने के लिए इस नंबर की आवश्यकता होगी। आदेश में इस संख्या AssemblyInfo.cs अपनी परियोजना के गुण में फ़ाइल को खोलने फ़ोल्डर और लाइन के साथ शुरू करने के लिए लग रहे प्राप्त करने के लिए: [विधानसभा: AssemblyVersion (

  3. सुनिश्चित करें कि आप की GUID पता बनाओ जेनरेटर क्लास। GENERATOR_GUID पैरामीटर बाद में निर्दिष्ट करने की आवश्यकता होगी। इस GUID को जेनरेटर क्लास के साथ फ़ाइल खोलने के लिए और GUID क्लास-एट्रिब्यूट जो इस वर्ग को सजाने के लिए, कुछ ऐसा करने के लिए: [Guid ("1779 9ई 85-421 बी -4684-बी 5 9ई -650E34ECC718")]

  4. प्रोजेक्ट

  5. असेंबली की सार्वजनिक टोकन कुंजी प्राप्त करें।

    sn.exe -टी ASSEMBLY_FILE

    आप इस जानकारी बाद में जब PUBLIC_TOKEN_KEY के लिए की आवश्यकता होगी: आपको निम्न आदेश चला करना होगा ऐसा करने के लिए। sn.exe फ़ाइल सी में पाया जा सकता है: में ढांचे के संस्करण संख्या (v8.0A) को \ Program Files \ Microsoft SDKs \ Windows \ v8.0A \ बिन \ sn.exe वेतन ध्यान ऊपर फ़ाइलपैथ। इसे परियोजना को संकलित करने के लिए उपयोग किए गए ढांचे के संस्करण के अनुरूप होना चाहिए।

    Gacutil.exe/मैं ASSEMBLY_FILE/च

    GAC में पंजीकृत हो रही प्रशासनिक अनुमति की आवश्यकता नहीं:

  6. निम्न आदेश का उपयोग कर GAC को विधानसभा रखो। Gacutil.exe फ़ाइल सी में पाया जा सकता है: \ Program Files \ Microsoft SDKs \ Windows \ v8.0A \ बिन \ NETFX 4.0 उपकरण \ Gacutil.exe वेतन ढांचे की संस्करण संख्या की ओर ध्यान (v8 .0 ए) ऊपर फ़ाइलपैथ में। इसे परियोजना को संकलित करने के लिए उपयोग किए गए ढांचे के संस्करण के अनुरूप होना चाहिए।

  7. .REG (नीचे देखें) फ़ाइल में निम्न परिवर्तन करें। कृपया ध्यान दें: {XXXXXXXXXXXX-XXXXXXXX-XXXXXXXXXXXX}

    7.1: कि दोनों GENERATOR_GUID और PROJECT_TYPE_GUID घुंघराले ब्रेसिज़ के साथ आपूर्ति किए जाने की जरूरत है। विजुअल स्टूडियो का संस्करण संख्या ठीक करें (उदाहरण के लिए: 10.0 या 9.0): VS_VERSION

    7.2। जनरेटर के GUID को ठीक करें: GENERATOR_GUID

    7.3। असेंबली के नामस्थान को ठीक करें: NAMESPACE_NAME

    7.4। जनरेटर वर्ग का नाम ठीक करें: GENERATOR_TYPE_NAME

    7.5।जनरेटर को पंजीकृत करने के लिए विजुअल स्टूडियो को यह जानने की जरूरत है कि इस जनरेटर को किस प्रोजेक्ट प्रकार पर लागू किया जा सकता है। तो आपको उचित परियोजना प्रकारों (सी #, वीबी.नेट, आदि) के GUID प्राप्त करने की आवश्यकता है। प्रोजेक्ट प्रकारों के GUID को जानने के लिए आपको एक टेक्स्ट स्टूडियो में एक दृश्य स्टूडियो प्रोजेक्ट फ़ाइल (* .csproj) खोलने की आवश्यकता है और ProjectTypeGuids XML तत्व में GUID की तलाश करें। इनमें से प्रत्येक GUIDs, एक GUID के साथ PROJECT_TYPE_GUID को प्रतिस्थापित करने वाली .REG फ़ाइल में पिछले 3 प्रविष्टियों के ब्लॉक को दोहराता है।

    7.6। कस्टम टूल से जुड़े फ़ाइल के विस्तार को ठीक करें: FILE_EXTENSTION

  8. .REG फ़ाइल चलाएं। ऐसा करने के लिए आपको व्यवस्थापकीय अनुमतियां होनी पड़ सकती हैं।

.REG फ़ाइल:

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\VS_VERSION\CLSID\GENERATOR_GUID] 
@="COM+ class: NAMESPACE_NAME.GENERATOR_TYPE_NAME" 
"InprocServer32"="C:\\WINDOWS\\system32\\mscoree.dll" 
"ThreadingModel"="Both" 
"Class"="NAMESPACE_NAME.GENERATOR_TYPE_NAME" 
"Assembly"="NAMESPACE_NAME, Version=ASSEMBLY_VERSION, Culture=Neutral, PublicKeyToken=PUBLIC_TOKEN_KEY" 

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

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\VS_VERSION\Generators\PROJECT_TYPE_GUID] 

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\VS_VERSION\Generators\PROJECT_TYPE_GUID\\.FILE_EXTENSTION] 
@="GENERATOR_TYPE_NAME" 

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\VS_VERSION\Generators\PROJECT_TYPE_GUID\GENERATOR_TYPE_NAME] 
@="Code generator for whatever you like" 
"CLSID"="GENERATOR_GUID" 
"GeneratesDesignTimeSource"=dword:00000001 

पी एस। आरईजी फ़ाइल में प्लेसहोल्डर को अलग करने में सक्षम नहीं होने के लिए खेद है, दुर्भाग्य से टेक्स्ट संपादक जो स्टैक ओवरव्लो का उपयोग सामग्री से अपने मार्कअप तत्वों को अलग नहीं कर सकता है।

+2

शायद ज़रुरत पड़े कोई है - मेरे जैसे - एक Windows 7 64 बिट स्थापना: उस मामले में रजिस्ट्री कुंजी में हैं: HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node Microsoft \ VisualStudio \ \ ... मैं Wow6432Node के बारे में पता नहीं था और कुछ समय बर्बाद कर बर्बाद कर दिया – PeterFromCologne

संबंधित मुद्दे

 संबंधित मुद्दे