Visual Studio: Who is writing to console? - visual-studio

OK, here's a good one (I think) - I'm working on an application with lots (far too many) dependency dlls, created by a team of developers. I'm trying to debug just one assembly, but the console output is 'polluted' by the Console.WriteLines and Debug.WriteLines left scattered around the code.
Is there anyway I can work out exactly which assembly a given line is coming from, so I can get the author to clean up their source?
UPDATE If you're also experiencing this kind of issue, note that there is another potential source of output messages which is any breakpoints with 'When hit' set to print a message. Having said which, this is a VERY cool feature, which can prevent the kind of problems I was having above.

Yes - replace Console.Out. Use Console.SetOut after creating a TextWriter which not only dumps the requested data to the original console, but also dumps a stack trace (and timestamp, and the requested data) to a file.
Here's some code, adapted from Benjol's answer:
(Note: you will want to adapt this code depending on whether you want a stack trace after each write, or after each writeline. In the code below, each char is followed by a stack trace!)
using System.Diagnostics;
using System.IO;
using System.Text;
public sealed class StackTracingWriter : TextWriter
{
private readonly TextWriter writer;
public StackTracingWriter (string path)
{
writer = new StreamWriter(path) { AutoFlush = true };
}
public override System.Text.Encoding Encoding
{
get { return Encoding.UTF8; }
}
public override void Write(string value)
{
string trace = (new StackTrace(true)).ToString();
writer.Write(value + " - " + trace);
}
public override void Write(char[] buffer, int index, int count)
{
Write(new string(buffer, index, count));
}
public override void Write(char value)
{
// Note that this will create a stack trace for each character!
Write(value.ToString());
}
public override void WriteLine()
{
// This is almost always going to be called in conjunction with
// real text, so don't bother writing a stack trace
writer.WriteLine();
}
protected override void Dispose(bool disposing)
{
writer.Dispose();
}
}
To use this for logging both Console.WriteLine and Debug.WriteLine to a file, make calls like this as early as possible in your code:
var writer = new StackTracingWriter(#"C:\Temp\ConsoleOut.txt");
Console.SetOut(writer);
Debug.Listeners.Add(new TextWriterTraceListener(writer));
Note that this currently doesn't also write to the original console. To do so, you'd need to have a second TextWriter (for the original console) in StackTracingWriter, and write to both places each time. Debug will however continue to be written to the original console.

Download Reflector and you can open up the mscorlib assembly, add your application's assemblies, then right click on the Console class and click Analyze and you can show all methods that reference the Console class.

Related

How to close Java Formatter, in finally or not?

I know that normally streams and formatters (particularly java.util.Formatter) in Java should be closed in finally to avoid from resource leaks. But here I am a little bit confused, because I see a lot of examples where people just close it without any finally block, especially the formatters. This question may have no sense to some people, but I want to be sure in what I am asking about.
Some examples from java2s.com and from tutorialspoint.com where the formatters are just closed without any block.
Please consider that my question is only for Java 6 and lower versions, because I know about try with resources.
Example:
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
Formatter formatter = new Formatter(buffer, Locale.US);
// format a new string
String name = "from java2s.com";
formatter.format("Hello %s !", name);
// print the formatted string
System.out.println(formatter);
// close the formatter
formatter.close();
// attempt to access the formatter results in exception
System.out.println(formatter);
}
In this specific example, it is not necessary to call close(). You only need to close the formatter if the underlying appender is Closable. In this case you are using a StringBuffer, which is not Closable so the call to close() does nothing. If you were to use Writer or PrintStream, those are closable and the call to close() would be necessary to avoid leaving the stream open.
If you are ever unsure if it is Closable it is best to just call close() anyway. No harm in doing so.
How about this, without further comments:
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
Formatter formatter = null;
try {
formatter = new Formatter(buffer, Locale.US);
String name = "from java2s.com";
formatter.format("Hello %s !", name);
System.out.println(formatter);
}
finally {
if (formatter != null) {
formatter.close();
}
}
}

How watch values doesn't affect the environment

When debugging in IDE, how does the IDE know how to calculate the watch value without changing the environment (writing to file, writing result to DB)?
Your observation cannot be generalized. An IDE typically makes changes during debugging, especially if a property has a side effect.
Visual Studio
The following C# code:
using System;
namespace EvaluateChangesValue
{
class Program
{
static void Main()
{
var program = new Program();
Console.WriteLine(program.Value);
Console.ReadLine();
Console.WriteLine(program.Value);
Console.ReadLine();
}
private int member;
private int Value => member++;
}
}
Set a breakpoint at the first ReadLine(), then add program.Value to the watch window and see how the value gets increased due to the member++ statement.
Eclipse
In Java and Eclipse, it's a bit harder to make the same proof because for these reasons:
In Java it's more clear whether you call a method or access a field.
You need the "Expressions" window, which is not available by default
Re-evaluation needs user interaction
The code is similar to C#:
public class Program {
public static void main(String[] args)
{
Program p = new Program();
System.out.println(p.member);
System.console().readLine();
System.out.println(p.member);
System.console().readLine();
}
private int member;
public int getMember()
{
return member++;
}
}
And the screenshot:

Generate Bare Definitions for a Project or Namespace (Visual Studio)

In developing an SDK for use within our product, we want to provide users (developers) a Visual Studio plugin, mainly to provide them Intellisense during their development and ensure their code compiles for them. To do this, we strip the contents of all of our SDK APIs and put them all in a separate project.
For example:
public IEnumerable<string> AvailableConnections(bool querySystem) {
var connections = ConnectionList();
if(querySystem)
connections = connections.Concat(SystemConnections());
... // Filter connections somehow
return connections;
}
public void WriteToStream(Stream strFrom, Stream strTo) {
byte[] buffer = new byte[32 * 1024]; // 32 KiB
int len;
while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
Becomes:
public IEnumerable<string> AvailableConnections(bool querySystem) { return null; }
public void WriteToStream(Stream strFrom, Stream strTo) { }
My question: Does a tool exist to automate this, whether for a particular project or particular namespace? Ideally, it would intake a project or namespace and output all of the public classes/functions replacing their definitions with a simple return of the return type's default value. Visual Studio seems to do almost this when you view a class from which you don't have the source (e.g., you'll see IEnumerable<T> [from metadata]).
It sounds like you want to provide interfaces to your API.
You can build this into your project and essentially you will always have an assembly that shows all the public members without containing your implementation code.
Create a project that contains only the API, and reference that from your main project so that your concrete code (your implementation) implements the interfaces.
The API assembly would contain mostly interfaces and perhaps some abstract classes an helper, which you could share with developers.
Taking your example, you would have an interface like
public interface IMySdkThing
{
IEnumerable<string> AvailableConnections(bool querySystem);
void WriteToStream(Stream strFrom, Stream strTo);
}
Your implementation would be declared like:
public class MySdkThing : IMySdkThing
{
// all the code you showed, just as it is
}
All that said, it isn't clear how this will be useful to the developer. He or she will need a dll with some actual, executable code in it to use your library. Intellisense and compile-time checking come for free; you don't have to do anything special.

Automatically detect when storing an object with ServiceStack.Redis

I am looking for a way to subscribe to events like Storing a specific object type to ServiceStack.Redis.
For example I may
using (var redisClient = new RedisClient())
using (var redisMyObjects = redisClient.As<MyObject>())
{
redisMyObjects.Store(myObject);//<-- I want this to trigger an event somehow
}
Is there anything like a OnStore event which I can hook too, anything out of the box? if not, is there any recommendation about how this should be done?
I don't think there is anything you can hook into (could be wrong).
Two options that came to mind:
1 - Make an extension method
2 - Publish a message to store your object and have a handler that listens for a response and does something. This is probably overkill since it's heading into the publish/subscribe realm. But, I think, worth looking into. (Basic example here and see Pub/Sub here).
Extension Method
public static class RedisClientExtensions
{
public static void StoreWithTrigger<T>(this IRedisTypedClient<T> redisClient, T value, Action<T> trigger)
{
redisClient.Store(value);
trigger(value);
}
}
Using ExtensionMethod
public void MyMethod()
{
using (var redisClient = new RedisClient())
using (var redisMyObjects = redisClient.As<MyObject>())
{
redisMyObjects.StoreWithTrigger<MyObject>(new MyObject(), TriggerEvent);//<-- I want this to trigger an event somehow
}
}
private void TriggerEvent<T>(T value)
{
//dosomething
}
Hope this gives you some ideas.

How do I write to the Visual Studio Output Window in My Custom Tool?

I am writing a custom tool and I currently have it doing what I want as far as functionality. I would like to be able to write to Visual Studio if something goes wrong. (Incorrectly formatted code or whatever).
Are there any standards for this? Right now I basically can force the tool to fail and Visual Studio puts in a warning that it has done so. I'd like a category in the Output window with any resulting messages I want to send. I could also live with a more descriptive task/warning in the Error list window.
Output Window
To write to the "General" output window in Visual Studio, you need to do the following:
IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;
Guid generalPaneGuid = VSConstants.GUID_OutWindowGeneralPane; // P.S. There's also the GUID_OutWindowDebugPane available.
IVsOutputWindowPane generalPane;
outWindow.GetPane( ref generalPaneGuid , out generalPane );
generalPane.OutputString( "Hello World!" );
generalPane.Activate(); // Brings this pane into view
If, however, you want to write to a custom window, this is what you need to do:
IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;
// Use e.g. Tools -> Create GUID to make a stable, but unique GUID for your pane.
// Also, in a real project, this should probably be a static constant, and not a local variable
Guid customGuid = new Guid("0F44E2D1-F5FA-4d2d-AB30-22BE8ECD9789");
string customTitle = "Custom Window Title";
outWindow.CreatePane( ref customGuid, customTitle, 1, 1 );
IVsOutputWindowPane customPane;
outWindow.GetPane( ref customGuid, out customPane);
customPane.OutputString( "Hello, Custom World!" );
customPane.Activate(); // Brings this pane into view
Details on IVsOutputWindow and IVsOutputWindowPane can be found on MSDN.
Error List
For adding items to the error list, the IVsSingleFileGenerator has a method call void Generate(...) which has a parameter of the type IVsGeneratorProgress. This interface has a method void GeneratorError() which lets you report errors and warnings to the Visual Studio error list.
public class MyCodeGenerator : IVsSingleFileGenerator
{
...
public void Generate( string inputFilePath, string inputFileContents, string defaultNamespace, out IntPtr outputFileContents, out int output, IVsGeneratorProgress generateProgress )
{
...
generateProgress.GeneratorError( false, 0, "An error occured", 2, 4);
...
}
...
}
The details of GeneratorError() can be found on MSDN.
There is another way using Marshal.GetActiveObject to grab a running DTE2 instance.
First reference EnvDTE and envdte80. This currently works in VisualStudio 2012, I haven't tried the others yet.
using System;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;
internal class VsOutputLogger
{
private static Lazy<Action<string>> _Logger = new Lazy<Action<string>>( () => GetWindow().OutputString );
private static Action<string> Logger
{
get { return _Logger.Value; }
}
public static void SetLogger( Action<string> logger )
{
_Logger = new Lazy<Action<string>>( () => logger );
}
public static void Write( string format, params object[] args)
{
var message = string.Format( format, args );
Write( message );
}
public static void Write( string message )
{
Logger( message + Environment.NewLine );
}
private static OutputWindowPane GetWindow()
{
var dte = (DTE2) Marshal.GetActiveObject( "VisualStudio.DTE" );
return dte.ToolWindows.OutputWindow.ActivePane;
}
}
If you want anything to appear in the Output window, it has to come from stdout. To do this, your app needs to be linked as a "console" app. Set the /SUBSYSTEM:CONSOLE flag in the project's property page, under Linker/System set the SubSystem property to CONSOLE.
Once you have your output in the window, if you include the text "Error:" it will appear as an error, or if you set "Warning:" it will appear as a warning. If your error text begins with a path/filename, followed by a line number in parenthesis, the IDE will recognize it as a "clickable" error, and navigate you automatically to the faulting line.
This is demonstrated in the following helper class from a Microsoft sample project:
https://github.com/microsoft/VSSDK-Extensibility-Samples/blob/df10d37b863feeff6e8fcaa6f4d172f602a882c5/Reference_Services/C%23/Reference.Services/HelperFunctions.cs#L28
The code is as follows:
using System;
using System.Diagnostics;
using Microsoft.VisualStudio.Shell.Interop;
namespace Microsoft.Samples.VisualStudio.Services
{
/// <summary>
/// This class is used to expose some utility functions used in this project.
/// </summary>
internal static class HelperFunctions
{
/// <summary>
/// This function is used to write a string on the Output window of Visual Studio.
/// </summary>
/// <param name="provider">The service provider to query for SVsOutputWindow</param>
/// <param name="text">The text to write</param>
internal static void WriteOnOutputWindow(IServiceProvider provider, string text)
{
// At first write the text on the debug output.
Debug.WriteLine(text);
// Check if we have a provider
if (null == provider)
{
// If there is no provider we can not do anything; exit now.
Debug.WriteLine("No service provider passed to WriteOnOutputWindow.");
return;
}
// Now get the SVsOutputWindow service from the service provider.
IVsOutputWindow outputWindow = provider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow;
if (null == outputWindow)
{
// If the provider doesn't expose the service there is nothing we can do.
// Write a message on the debug output and exit.
Debug.WriteLine("Can not get the SVsOutputWindow service.");
return;
}
// We can not write on the Output window itself, but only on one of its panes.
// Here we try to use the "General" pane.
Guid guidGeneral = Microsoft.VisualStudio.VSConstants.GUID_OutWindowGeneralPane;
IVsOutputWindowPane windowPane;
if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.GetPane(ref guidGeneral, out windowPane)) ||
(null == windowPane))
{
if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.CreatePane(ref guidGeneral, "General", 1, 0)))
{
// Nothing to do here, just debug output and exit
Debug.WriteLine("Failed to create the Output window pane.");
return;
}
if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.GetPane(ref guidGeneral, out windowPane)) ||
(null == windowPane))
{
// Again, there is nothing we can do to recover from this error, so write on the
// debug output and exit.
Debug.WriteLine("Failed to get the Output window pane.");
return;
}
if (Microsoft.VisualStudio.ErrorHandler.Failed(windowPane.Activate()))
{
Debug.WriteLine("Failed to activate the Output window pane.");
return;
}
}
// Finally we can write on the window pane.
if (Microsoft.VisualStudio.ErrorHandler.Failed(windowPane.OutputString(text)))
{
Debug.WriteLine("Failed to write on the Output window pane.");
}
}
}
}
You can use the Debug and/or Trace classes. There is some information here:
http://msdn.microsoft.com/en-us/library/bs4c1wda(VS.71).aspx
Best of luck.
use System.Diagnostics.Debugger.Message

Resources