using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using EnvDTE; using System.Runtime.InteropServices; namespace Reformatter { class Program { [STAThread] static void Main(string[] args) { if (args.Length != 1) { System.Console.WriteLine("Syntax: one argument: a file which will be run through Visual Studio's auto-formatter."); } else { var file = args[0]; if (!Path.IsPathRooted(file)) { file = Directory.GetCurrentDirectory() + "\\" + file; } FormatFile(file); } } static void FormatFile(string file) { EnvDTE.Solution soln = System.Activator.CreateInstance( Type.GetTypeFromProgID("VisualStudio.Solution.12.0")) as EnvDTE.Solution; // Registering the message filter lets us retry commands that the threading model // can't handle at the moment because windows is stupid and hasn't built up their // com interface stuff to handle multiple requests simultaneously MessageFilter.Register(); { var window = soln.DTE.ItemOperations.OpenFile(file); TextSelection selection = window.Selection as TextSelection; selection.SelectAll(); selection.SmartFormat(); soln.DTE.ActiveDocument.Save(); } MessageFilter.Revoke(); } public class MessageFilter : IOleMessageFilter { // // Class containing the IOleMessageFilter // thread error-handling functions. // Start the filter. public static void Register() { IOleMessageFilter newFilter = new MessageFilter(); IOleMessageFilter oldFilter = null; var result = CoRegisterMessageFilter(newFilter, out oldFilter); if (result != 0) { System.Console.WriteLine("Error 0x{0:X}", result); } } // Done with the filter, close it. public static void Revoke() { IOleMessageFilter oldFilter = null; var result = CoRegisterMessageFilter(null, out oldFilter); if (result != 0) { System.Console.WriteLine("Error 0x{0:X}", result); } } // // IOleMessageFilter functions. // Handle incoming thread requests. int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo) { //Return the flag SERVERCALL_ISHANDLED. return 0; } // Thread call was rejected, so try again. int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType) { if (dwRejectType == 2) // flag = SERVERCALL_RETRYLATER. { // Retry the thread call immediately if return >=0 & // <100. return 99; } // Too busy; cancel call. return -1; } int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType) { //Return the flag PENDINGMSG_WAITDEFPROCESS. return 2; } // Implement the IOleMessageFilter interface. [DllImport("Ole32.dll")] private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, out IOleMessageFilter oldFilter); } [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] interface IOleMessageFilter { [PreserveSig] int HandleInComingCall( int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo); [PreserveSig] int RetryRejectedCall( IntPtr hTaskCallee, int dwTickCount, int dwRejectType); [PreserveSig] int MessagePending( IntPtr hTaskCallee, int dwTickCount, int dwPendingType); } } }