2009-07-23 15 views
36

क्या किसी को पता है कि क्लिपबोर्ड पर विजुअल स्टूडियो "सिंबल सिंबल परिणाम" विंडो में सभी लाइनों की प्रतिलिपि कैसे करें? आप एक पंक्ति की प्रतिलिपि बना सकते हैं, लेकिन मैं उन्हें सभी कॉपी करना चाहता हूं।क्या मैं विजुअल स्टूडियो "प्रतीक परिणाम ढूंढें" विंडो से कई पंक्तियां कॉपी कर सकता हूं?

मुझे विश्वास नहीं है कि मैं ऐसा करने वाला पहला व्यक्ति हूं, लेकिन मुझे इस स्पष्ट रूप से अनुपलब्ध सुविधा के बारे में कोई चर्चा भी नहीं मिल सकती है।

उत्तर

17

यहाँ के लिए एक वैश्विक मिल रहा है हो सकता है कुछ कोड क्लिपबोर्ड सभी पाठ की प्रतिलिपि करने के लिए नेट स्वचालन पुस्तकालय का उपयोग करता है है।

एक नया WinForms परियोजना शुरू करें और फिर निम्न संदर्भ जोड़ें: WindowsBase

  • UIAutomationTypes
  • UIAutomationClient
  • System.Xaml
  • PresentationCore
  • PresentationFramework
    • सिस्टम। प्रबंधन

    कोड यह भी बताता है कि क्लिपबोर्ड पर सामग्री की प्रतिलिपि बनाने के लिए दृश्य स्टूडियो में मेनू आइटम कैसे सेट अप करें।

    संपादित करें: यूआई ऑटोमेशन केवल दृश्य वृक्ष दृश्य आइटम लौटाता है। इस प्रकार, सभी वस्तुओं की प्रतिलिपि बनाने के लिए, खोज प्रतीक परिणाम विंडो को अग्रभूमि के रूप में सेट किया गया है, और फिर {PGDN} भेजा जाता है, और आइटम के अगले बैच की प्रतिलिपि बनाई जाती है। इस प्रक्रिया को तब तक दोहराया जाता है जब तक कोई नई वस्तु नहीं मिल जाती। यह ScrollPattern का उपयोग करने के लिए बेहतर होता, हालांकि स्क्रॉल सेट करने का प्रयास करते समय इसे Exception फेंक दिया गया।

    संपादित करें 2: एक अलग थ्रेड पर चलकर AutomationElement FindAll के प्रदर्शन में सुधार करने का प्रयास किया। कुछ मामलों में धीमी लगती है।

    संपादित करें 3: TreeView विंडो को बहुत बड़ा बनाकर बेहतर प्रदर्शन। लगभग 10 सेकंड में लगभग 400 आइटम कॉपी कर सकते हैं।

    संपादित करें 4:IDisposable लागू करने वाली वस्तुओं का निपटान करें। बेहतर संदेश रिपोर्टिंग। प्रक्रिया का बेहतर प्रबंधन तर्क है। विंडो को अपने मूल आकार में वापस रखें।

    enter image description here

    using System; 
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Diagnostics; 
    using System.Management; 
    using System.Runtime.InteropServices; 
    using System.Text; 
    using System.Threading; 
    using System.Windows.Automation; 
    using System.Windows.Forms; 
    
    namespace CopyFindSymbolResults { 
    
    // This program tries to find the 'Find Symbol Results' window in visual studio 
    // and copy all the text to the clipboard. 
    // 
    // The Find Symbol Results window uses a TreeView control that has the class name 'LiteTreeView32' 
    // In the future if this changes, then it's possible to pass in the class name as the first argument. 
    // Use TOOLS -> Spy++ to determine the class name. 
    // 
    // After compiling this code into an Exe, add a menu item (TOOLS -> Copy Find Symbol Results) in Visual Studio by: 
    // 1) TOOLS -> External Tools... 
    //  (Note: in the 'Menu contents:' list, count which item the new item is, starting at base-1). 
    //  Title: Copy Find Symbol Results 
    //  Command: C:\<Path>\CopyFindSymbolResults.exe    (e.g. C:\Windows\ is one option) 
    // 2) TOOLS -> Customize... -> Keyboard... (button) 
    //  Show Commands Containing: tools.externalcommand 
    //  Then select the n'th one, where n is the count from step 1). 
    // 
    static class Program { 
    
        enum Tabify { 
         No = 0, 
         Yes = 1, 
         Prompt = 2, 
        } 
    
        [STAThread] 
        static void Main(String[] args) { 
    
         String className = "LiteTreeView32"; 
         Tabify tabify = Tabify.Prompt; 
    
         if (args.Length > 0) { 
          String arg0 = args[0].Trim(); 
          if (arg0.Length > 0) 
           className = arg0; 
    
          if (args.Length > 1) { 
           int x = 0; 
           if (int.TryParse(args[1], out x)) 
            tabify = (Tabify) x; 
          } 
         } 
    
         DateTime startTime = DateTime.Now; 
         Data data = new Data() { className = className }; 
    
         Thread t = new Thread((o) => { 
          GetText((Data) o); 
         }); 
         t.IsBackground = true; 
         t.Start(data); 
    
         lock(data) { 
          Monitor.Wait(data); 
         } 
    
         if (data.p == null || data.p.MainWindowHandle == IntPtr.Zero) { 
          System.Windows.Forms.MessageBox.Show("Cannot find Microsoft Visual Studio process."); 
          return; 
         } 
    
         try { 
    
         SimpleWindow owner = new SimpleWindow { Handle = data.MainWindowHandle }; 
    
         if (data.appRoot == null) { 
          System.Windows.Forms.MessageBox.Show(owner, "Cannot find AutomationElement from process MainWindowHandle: " + data.MainWindowHandle); 
          return; 
         } 
    
         if (data.treeViewNotFound) { 
          System.Windows.Forms.MessageBox.Show(owner, "AutomationElement cannot find the tree view window with class name: " + data.className); 
          return; 
         } 
    
         String text = data.text; 
         if (text.Length == 0) { // otherwise Clipboard.SetText throws exception 
          System.Windows.Forms.MessageBox.Show(owner, "No text was found: " + data.p.MainWindowTitle); 
          return; 
         } 
    
         TimeSpan ts = DateTime.Now - startTime; 
    
         if (tabify == Tabify.Prompt) { 
          var dr = System.Windows.Forms.MessageBox.Show(owner, "Replace dashes and colons for easy pasting into Excel?", "Tabify", System.Windows.Forms.MessageBoxButtons.YesNo); 
          if (dr == System.Windows.Forms.DialogResult.Yes) 
           tabify = Tabify.Yes; 
    
          ts = TimeSpan.Zero; // prevent second prompt 
         } 
    
         if (tabify == Tabify.Yes) { 
          text = text.Replace(" - ", "\t"); 
          text = text.Replace(" : ", "\t"); 
         } 
    
         System.Windows.Forms.Clipboard.SetText(text); 
    
         String msg = "Data is ready on the clipboard."; 
         var icon = System.Windows.Forms.MessageBoxIcon.None; 
    
         if (data.lines != data.count) { 
          msg = String.Format("Only {0} of {1} rows copied.", data.lines, data.count); 
          icon = System.Windows.Forms.MessageBoxIcon.Error; 
         } 
    
         if (ts.TotalSeconds > 4 || data.lines != data.count) 
          System.Windows.Forms.MessageBox.Show(owner, msg, "", System.Windows.Forms.MessageBoxButtons.OK, icon); 
    
         } finally { 
          data.p.Dispose(); 
         } 
        } 
    
        private class SimpleWindow : System.Windows.Forms.IWin32Window { 
         public IntPtr Handle { get; set; } 
        } 
    
        private const int TVM_GETCOUNT = 0x1100 + 5; 
    
        [DllImport("user32.dll")] 
        static extern int SendMessage(IntPtr hWnd, int msg, int wparam, int lparam); 
    
        [DllImport("user32.dll", SetLastError = true)] 
        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint); 
    
        private class Data { 
         public int lines = 0; 
         public int count = 0; 
         public IntPtr MainWindowHandle = IntPtr.Zero; 
         public IntPtr TreeViewHandle = IntPtr.Zero; 
         public Process p; 
         public AutomationElement appRoot = null; 
         public String text = null; 
         public String className = null; 
         public bool treeViewNotFound = false; 
        } 
    
        private static void GetText(Data data) { 
         Process p = GetParentProcess(); 
         data.p = p; 
    
         if (p == null || p.MainWindowHandle == IntPtr.Zero) { 
          data.text = ""; 
          lock(data) { Monitor.Pulse(data); } 
          return; 
         } 
    
         data.MainWindowHandle = p.MainWindowHandle; 
         AutomationElement appRoot = AutomationElement.FromHandle(p.MainWindowHandle); 
         data.appRoot = appRoot; 
    
         if (appRoot == null) { 
          data.text = ""; 
          lock(data) { Monitor.Pulse(data); } 
          return; 
         } 
    
         AutomationElement treeView = appRoot.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ClassNameProperty, data.className)); 
         if (treeView == null) { 
          data.text = ""; 
          data.treeViewNotFound = true; 
          lock(data) { Monitor.Pulse(data); } 
          return; 
         } 
    
         data.TreeViewHandle = new IntPtr(treeView.Current.NativeWindowHandle); 
         data.count = SendMessage(data.TreeViewHandle, TVM_GETCOUNT, 0, 0); 
    
         RECT rect = new RECT(); 
         GetWindowRect(data.TreeViewHandle, out rect); 
    
         // making the window really large makes it so less calls to FindAll are required 
         MoveWindow(data.TreeViewHandle, 0, 0, 800, 32767, false); 
         int TV_FIRST = 0x1100; 
         int TVM_SELECTITEM = (TV_FIRST + 11); 
         int TVGN_CARET = TVGN_CARET = 0x9; 
    
         // if a vertical scrollbar is detected, then scroll to the top sending a TVM_SELECTITEM command 
         var vbar = treeView.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Vertical Scroll Bar")); 
         if (vbar != null) { 
          SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, 0); // select the first item 
         } 
    
         StringBuilder sb = new StringBuilder(); 
         Hashtable ht = new Hashtable(); 
    
         int chunk = 0; 
         while (true) { 
          bool foundNew = false; 
    
          AutomationElementCollection treeViewItems = treeView.FindAll(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TreeItem)); 
          if (treeViewItems.Count == 0) 
           break; 
    
          if (ht.Count == 0) { 
           chunk = treeViewItems.Count - 1; 
          } 
    
          foreach (AutomationElement ele in treeViewItems) { 
           try { 
            String n = ele.Current.Name; 
            if (!ht.ContainsKey(n)) { 
             ht[n] = n; 
             foundNew = true; 
             data.lines++; 
             sb.AppendLine(n); 
            } 
           } catch {} 
          } 
    
          if (!foundNew || data.lines == data.count) 
           break; 
    
          int x = Math.Min(data.count-1, data.lines + chunk); 
          SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, x); 
         } 
    
         data.text = sb.ToString(); 
         MoveWindow(data.TreeViewHandle, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, false); 
         lock(data) { Monitor.Pulse(data); } 
        } 
    
        // this program expects to be launched from Visual Studio 
        // alternative approach is to look for "Microsoft Visual Studio" in main window title 
        // but there could be multiple instances running. 
        private static Process GetParentProcess() { 
         // from thread: http://stackoverflow.com/questions/2531837/how-can-i-get-the-pid-of-the-parent-process-of-my-application 
         int myId = 0; 
         using (Process current = Process.GetCurrentProcess()) 
          myId = current.Id; 
         String query = String.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId); 
         using (var search = new ManagementObjectSearcher("root\\CIMV2", query)) { 
          using (ManagementObjectCollection list = search.Get()) { 
           using (ManagementObjectCollection.ManagementObjectEnumerator results = list.GetEnumerator()) { 
            if (!results.MoveNext()) return null; 
            using (var queryObj = results.Current) { 
             uint parentId = (uint) queryObj["ParentProcessId"]; 
             return Process.GetProcessById((int) parentId); 
            } 
           } 
          } 
         } 
        } 
    
        [DllImport("user32.dll")] 
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 
    
        [StructLayout(LayoutKind.Sequential)] 
        private struct RECT { 
         public int Left; 
         public int Top; 
         public int Right; 
         public int Bottom; 
        } 
    } 
    } 
    
  • +0

    यह प्रभावशाली है। इसे पोस्ट करने के लिए धन्यवाद। मैं इसे आजमाने के लिए इंतजार नहीं कर सकता। –

    +0

    @ श्री पुट्टी क्या यह आपके लिए काम करता है? – Loathing

    +0

    यह मेरे लिए बहुत अच्छा काम करता है। मुझे वीएस 2013 के लिए "सिस्टम.मैनेजमेंट" जोड़ना पड़ा। – mojo

    -1

    मेरे पिछले अनुभव और कुछ परीक्षणों से मैंने अभी किया है, ऐसा करने के लिए कोई सुविधा नहीं है।

    आप ऐसा क्यों करना चाहते हैं? आप क्लिपबोर्ड पर सभी संदर्भों की प्रतिलिपि क्यों बनाना चाहते हैं? जैसा कि मैं समझता हूं कि इन सुविधाओं की गति सभी संदर्भों की स्थिर प्रतिलिपि बनाएगी, अपेक्षाकृत बेकार होगी यदि आप गतिशील और पूर्ण प्रतिलिपि जल्दी से उत्पन्न कर सकते हैं।

    आप इस कार्यक्षमता को जोड़ने के लिए हमेशा दृश्य स्टूडियो का विस्तार कर सकते हैं, this post अंडेहेड कैफे पर देखें।

    +3

    मैं यह नहीं कह सकता कि ये खोज मेरे लिए जल्दी से पूर्ण हो गई हैं। मेरे पास कई परस्पर निर्भर परियोजनाओं के साथ एक बड़ा समाधान है और प्रतीकों की खोज में कई मिनट लगते हैं (और नहीं, मेरी मशीन कुल कुत्ता नहीं है)। इसके अतिरिक्त, आउटपुट में कई सौ रेखाएं होती हैं, जो कुछ हद तक बोझिल होती हैं। दुर्भाग्यवश, ये खोजें स्मार्ट हैं जो कुछ भी मैं आसानी से मैन्युअल रूप से कर सकता हूं और मैं भी कई समान खोजों के आउटपुट की तुलना करने में सक्षम होना चाहता हूं। शायद मैं आज सिर्फ क्रैकी हूं, लेकिन मेरे लिए यह वास्तव में एक अनुपलब्ध विशेषता प्रतीत होता है। –

    +0

    मैं विजुअल स्टूडियो में काफी हद तक विस्तार से खेल रहा हूं और मध्यवर्ती ट्यूटोरियल्स और दस्तावेज़ीकरण के बावजूद आप दृश्य स्टूडियो का विस्तार करने के लिए बहुत सी अच्छी चीजें कर सकते हैं, और एक ऐड ऑन शुरू करना एक जादूगर दूर है। मैं आपको इसे जोड़ने के लिए प्रोत्साहित करता हूं, क्योंकि ऐसा करना मुश्किल नहीं होना चाहिए। – user142350

    1

    एक ही आवश्यकता थी और हाइपरनेप नामक एक स्क्रीनशॉट टूल का उपयोग कर इसे हल कर रहे थे जिसमें कुछ बुनियादी ओसीआर कार्यक्षमता भी थी।

    2

    मैंने मैक्रो एक्सप्रेस का उपयोग करके इसे हल किया। उनके पास 30-दिन का नि: शुल्क परीक्षण है जिसका मैंने उपयोग किया क्योंकि यह मेरे लिए एक बंद है। मैंने सभी खोज प्रतीक परिणामों की प्रतिलिपि बनाने के लिए एक सरल मैक्रो लिखा, एक समय में एक पंक्ति, नोटपैड दस्तावेज़ में।

    अनुक्रम: * दोहराएँ (x) बार (हालांकि कई प्रतीक परिणाम आपके पास) * सक्रिय प्रतीक परिणाम विंडो * देरी .5 सेकंड * अनुकरण कीस्ट्रोक्स "तीर डाउन" * क्लिपबोर्ड कॉपी * सक्रिय नोटपैड का पता लगाएं खिड़की * देरी .5 सेकंड * क्लिपबोर्ड पेस्ट * कीस्ट्रोक्स अनुकरण "Enter" * अंत दोहराएँ

    +0

    ओपन सोर्स विकल्प: [ऑटोहॉटकी] (http://www.autohotkey.com/), [सिकुली] (http://www.sikuli.org/)। –

    +0

    @ सिकुली - मुझे ऑटोहॉटकी पसंद है! खैर, मुझे भी इससे नफरत है, लेकिन यह कई समस्याओं को हल करता है। मैं इसे एएचके के साथ स्वचालित करने के लिए चीजों की अपनी लंबी सूची में जोड़ दूंगा, लेकिन मुझे लगता है कि माइक्रोसॉफ्ट हमें किनारों के चारों ओर नीचे जाने दे रहा है। –

    1

    आप वैश्विक ढूंढने के लिए अभिव्यक्ति के रूप में अपने प्रतीक सांकेतिक शब्दों में बदलना कर सकते हैं तो कॉपी-पेस्ट का पता लगाएं परिणाम विंडो से सभी परिणाम आसान है।

    जैसे संपत्ति 'foo' के सभी संदर्भों को खोजने आप '.foo'

    +2

    हां, यह सच है, लेकिन सभी संदर्भों की तुलना में मुझे थोड़ा अधिक स्मार्ट लगता है, और कभी-कभी मैं वास्तव में अपनी शक्ति चाहता हूं। यह मुझे दुखी करता है कि सामान्य 'खोज परिणाम' विंडो में एक कॉपी कमांड होता है जबकि 'सिंबल सिंबल परिणाम' विंडो नहीं होती है। –

    +0

    यह एक खराब कामकाज नहीं है, खासकर यदि आप नियमित अभिव्यक्तियों का उपयोग करते हैं (लेकिन यह तब भी बेहतर होगा यदि आप खोज प्रतीक विंडो से सबकुछ कॉपी कर सकें) – TooTone

    -1

    अरे किसी तरह आप किसी अन्य तरीके से इस लक्ष्य को हासिल कर सकते हैं,

    बस 'FindAll' चयनित पाठ और आप सभी लाइनों

    0

    दृश्य स्टूडियो कोड को पकड़ने के लिए सक्षम हो जाएगा एक ब्राउज़र के रूप में काम करता है। सहायता> डेवलपर टूल

    डेवलपर उपकरण कंसोल के लिए निम्न निर्देश लिखने टॉगल:

    var elementos = document.getElementsByClassName("plain match") 
    console.log(elementos.length) 
    for(var i = 0; i<elementos.length;i++) console.log(elementos[i].title) 
    

    और यह डेवलपर उपकरण खोलने के लिए और कोड

    मेनू के उस भाग के लिए खोज करने के लिए संभव है आप मैच के परिणाम देख सकते हैं।

    अब आप परिणाम

    screen shot

    0

    मैं एक ही समस्या थी कॉपी कर सकते हैं। मुझे एक निश्चित विधि और उसके कुछ अधिभारित संस्करण के सभी अवसरों की एक सूची बनाना पड़ा।

    मेरी समस्या को हल करने के लिए मैंने रीशेपर का उपयोग किया। (ReSharper -> खोजें -> उपयोग उन्नत खोजें)।

    इसमें भी एक बहुत अच्छी सारणीबद्ध टेक्स्ट निर्यात सुविधा है।

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