Friday, June 26, 2015

Sometimes a Gem: How to investigate/debug Microsoft Fakes build error

So I was having a d@%n issue with VS2015, which was refusing to create a fake stub for me, with the not-helpful-at-all error "failed to generate stub type for type (...)". Nothing in the build output log, nothing anywhere to explain what was going on.

Google has never been so unhelpful, which is to say, he helped me only at the fourth or fifth entry.

This post includes a gem:

To debug the build issue, open the assembly.fake xml file in the Fakes folder added automatically to your project. Add the two parameters Diagnostic=”true” Verbosity=”Noisy” to the fake element, like this:
(...)

Then in Tools|Options under Projects and Solutions|Build and Run, change the MSBuild project output verbosity to ‘Diagnostic’. Build again and in the generated output, look for Task “GenerateFakes” 

It worked like a charm. Thanks David!


Tuesday, June 16, 2015

Name a file or folder with a starting dot

So, in linux hidden folders and files begin with a dot. In windows, it was considered forbidden to create such files (at least I believed it so in FAT32), but now you can see a number of tools creating file system entries with that naming scheme (git, for instance). But, as a user, can I name anything like that?

Let's try to create a folder that is dot-starting:

Sexy naming
The result is not what we wanted:

Type a filename, it says. We just did, dummy!

Well, Windows think we didn't typed a name. That's scary, we did! Or, maybe not? For Windows, it seems, everything after the dot is considered an extension, so, in this case, we just provided an extension for the file (not a name).

To go around this issue, you have to make windows understand that ".dotstarted" is the name, not the extension. And what is the extension in this case, you may ask? The empty string, of course. So, the full name, with the extension, would be...

File with extensions

We just specified the empty string as the extension, making sure Windows understands the ".dotstarted" part as the name. This results on it being correctly created, be it a directory or a simple file. 

Sunday, May 17, 2015

Remove All Nugets From All Projects

This may never be used in your usual conditions, however, I found it to be useful at least once: NuGet packages got messed up after some merges, with different versions in different projects. So I wrote a one-liner to remove all the packages from all the projects in the solution.

All you have to do is paste this snippet into the Package Manager Console.

Get-Project -All | %{ $projectName = $_.ProjectName; foreach($package in Get-Package -ProjectName $projectName) { Uninstall-Package -ProjectName $projectName -Id $package.Id -Force }}


All thanks to this reference.

Monday, April 27, 2015

Let's ask together for better Visual Studio support for Git

Ugh, three times already! I'm using Visual Studio with Git and for the third time I've pushed some changes at work, only to pull those at home and find out that a few files are missing from the repo. What is that?

When Microsoft announced that Visual Studio would support Git and, what's more, Visual Studio Online (their "cloud" TFS, not Visual Studio) would have Git as well as the old, SourceSafe engine, I was thrilled. What a wonder: the magic tooling that only Microsoft is ever able to give us, and a modern repository, and a distributed one at that.

About two years later and I finally did a deep dive on that support and I must say, I'm pretty disappointed. I always thought the interface clumsy and, in the past, I reverted to using SourceTree, which is still my favorite Git client. But right now I'm working on a client environment and I have no choice but to use their machine. And this also means not being able to install anything, which means - you guessed! - using only Visual Studio support for this.

Now, besides the clumsy interface, I've realized that the support is incomplete, missing a number of features from Git, and even worse, the bad support can lead to mistakes as the one on the first paragraph:
  • Visual Studio allows committing with untracked files. This is my major peeve, as you all can see in the first paragraph. SourceTree simply enforces that either we ignore or push the file. I think it makes a lot of sense, and avoid problems such as the one I suffered.
  • Better history view. Checking a file history through Visual Studio is doable, but not fine. I know that this isn't something easy to do through Git's command line as well, but VS can do better.
  • Better Navigation. Oh my god! Clicking a dropdown to choose whether I want to see changes, branches or  whatever... I think this can be much improved. Why do we have to have a small screen with the complex navigation, when we can have a full screen like a real tool? Yeah, that would break VS look 'n feel, but what of it? What is more important?
I'll keep myself to those three points. There are other places where it could be better, of course, but those three would make me very happy.

Monday, December 22, 2014

Embedding DLL's

I've faced this problem before, and ended up with the same solution: I have to deploy a solution that is composed of more than one file, usually an exe and a set of DLL's.

But the deployment process expects only a single file. With Java, this is simple; Maven can pack every dependency together and a single jar file is generated for your application. But how we solve this with .NET and it's multiple DLL nature?

 MSFT Research created a tool for that, called ILMerge.

However, this tool has shortcomings, such as it's unability to work with WPF. Now, what I've done in the past (when I needed to include a native DLL to do some interop, actually) is much more like the solution presented here. In short, all you do is embed the DLL's as resources in your main assembly (be it a executable or library), and add an event handler to the AssemblyResolve property of the current appdomain

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {

   String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";

   using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) 
   {
      Byte[] assemblyData = new Byte[stream.Length];
      stream.Read(assemblyData, 0, assemblyData.Length);
      return Assembly.Load(assemblyData);
   }
}

This will result in the appdomain loading the embedded DLL as resources. The code above can be adapted to even load executables if necessary.