Congratulations, your tool has users! But now complaints are pouring in.
Unfortunately, very few developers will have the time or patience to send poke around or follow instructions for finding your debugging output to help you figure things out.
With a single click, the following code opens up a user's default email client (e.g. Outlook) addressed to you, with the file attached and a body explaining the data being sent and an option to see it. Then, they just have to click send.
There are no third party dependencies.
Zipping a file
automark.VisualStudio/automark.VisualStudioPackage.cs
First, setup things on disk. builder
is a StringBuilder that contains the exported contents. tempExport
is the file we want to zip, as tempExportZip
.
var time = DateTime.Now;
string tempExport = System.IO.Path.Combine(m_basePath, "exports", string.Format("export-{0:yyyy-MM-dd-hh-mm-tt}.export", time));
string tempExportZip = System.IO.Path.Combine(m_basePath, "exports", string.Format("export-{0:yyyy-MM-dd-hh-mm-tt}.zip", time));
var parent = System.IO.Path.GetDirectoryName(tempExport);
if (!System.IO.Directory.Exists(parent))
{
System.IO.Directory.CreateDirectory(parent);
}
System.IO.File.WriteAllText(tempExport, builder.ToString());
Zip.ZipFile(tempExportZip, tempExport);
automark
is a tool for generating a markdown summary of a coding task from recent coding history. It designed work with another tool, autogit, which records fine-grain code changes in the IDE.
Something a little different about this blog post is that this doesn't aim to be a perfect how-to document, but instead, show incremental progress and mistakes along the way.
Coding Summary, Friday, October 11, 2013
I will be showing one example usage of automark, by showing you a blog post generated from a recent coding task. The goal of the task was to create a light-weight shim for Visual Studio to run and launch automark, which currently works as a command line tool, from the IDE itself.
Setting up VSX package
ProvideAutoLoad
is necessary for getting Visual Studio package to load automatically.
automark.VisualStudio/automark.VisualStudioPackage.cs
// This attribute registers a tool window exposed by this package.
[ProvideToolWindow(typeof(MyToolWindow))]
[Guid(GuidList.guidautomarkVisualStudioPkgString)]
+ [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class automarkVisualStudioPackage : Package
{
/// <summary>
Visual Studio actually provides a powerful framework for making custom extensions to the editor while keeping the code surprisingly simple.
Imagine if you wanted to make a // TODO
note appear more distinctive as well as provide custom actions.
With Visual Studio Extensions and MEF, you can make direct graphical changes to the editor with an IAdornmentLayer
. But if you want to support custom editor actions and more interactivity, it is worth it to also create an ITagger
. This post will show how you can insert tags into the TextBuffer
and query those to render custom adornments.
Adornments
First, we create a class that will respond to text view creation events and create an IAdornmentLayer
TodoArdornmentFactory.cs
We provide MEF attributes so that the class will merge into the IWpfTextViewCreationListener
MEF container.
/// <summary>
/// Establishes an <see cref="IAdornmentLayer"/> to place the adornment on and exports the <see cref="IWpfTextViewCreationListener"/>
/// that instantiates the adornment on the event of a <see cref="IWpfTextView"/>'s creation
/// </summary>
[Export(typeof(IWpfTextViewCreationListener))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class TodoArdornmentFactory : IWpfTextViewCreationListener
{
Deploying Native Binaries
If your extension depends on a native binary, you have to do some tricks to get the binary to be copied into the experimental hive directory for testing and including in your VSIX for deployment.
I was doing some manual copies in my post build event that was brittle, and had to explicitly include the native binaries as content
.
Another way
nulltoken had given out a helpful hint on using msbuild directives to stream-line this process:
You might be willing to glance at
https://github.com/libgit2/libgit2sharp/blob/vNext/LibGit2Sharp/CopyNativeDependencies.targets and the way it's being used in LibGit2Sharp.Tests.csproj
How to do it
I adapted this approach for my project. First, I define a reference to native binaries that live in the nuget directory. $(MSBuildProjectDirectory)
refers to directory containing the .csproj file.
<PropertyGroup>
<NativeBinariesDirectory>$(MSBuildProjectDirectory)\..\packages\LibGit2Sharp.0.13.0.0\NativeBinaries</NativeBinariesDirectory>
</PropertyGroup>
A simple example for parsing the output of git log in pure C#.
Getting git log output
Get output of git log --name-status
by specifying path of git repo.
public static string ListShaWithFiles(string path)
{
var output = RunProcess(string.Format(" --git-dir={0}/.git --work-tree={1} log --name-status", path.Replace("\\", "/"), path.Replace("\\", "/")));
return output;
}
Helper for getting command line output
private static string RunProcess(string command)
{
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = Config.GitExectuable;
p.StartInfo.Arguments = command;
p.Start();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return output;
}