How can I disable specific Visual Studio Commands from my Package? - resharper

I am creating a package which requires the text white space be in a specific format. Without arguing about the reason why lets just assume this is an okay requirement. I must then prevent visual studio from auto-updating the code.
This is fairly easy from an open document where I can add a command filter and prevent the command from being executed with the following code.
[Export(typeof(IVsTextViewCreationListener))]
internal sealed class MyListener : IVsTextViewCreationListener
{
public void VsTextViewCreated(IVsTextView textViewAdapter)
{
var filter = PackageManager.Kernel.Get<CommandFilter>();
if (ErrorHandler.Succeeded(textViewAdapter.AddCommandFilter(filter,out var next)))
filter.Next = next;
}
}
public class CommandFilter : IOleCommandTarget
{
public IOleCommandTarget Next { get; set; }
public const uint CmdEditFormat = 0x8F;
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
switch (prgCmds[0].cmdID)
{
case CmdEditFormat:
return VSConstants.E_ABORT;
return Next.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
}
The Edit.FormatDocument command id is blocked as I require. I could also add Edit.FormatSelection or any other commands that may affect the white-space. This is all well and good for open documents which I mark with this special need.
However, when it comes to add-ins like Resharper which updated files in a multitude of ways without actually opening the files themselves there becomes trouble. I need to also block some of these commands, once I find which ones are volatile to my implementation.
So the question is can I setup some sort of CommandFilter application-wide so I can catch them in the act? This would allow me cleanup command of Resharper and then restore the files that contain formatting as needed.
Another possibility is if I can find where the Resharper options file is and updated it somehow to exclude said files. I know this is manually possible.

Related

How to differentiate color scheme

I would like to change color scheme Eiffel so that the keyword class in java files will be different color than keyword int? If I change Storage in Eiffel, both keywords change the color.
You need to find out the exact scopes of class and int. The PackageResourceViewer is a great way to open files inside .sublime-package files.
Once installed, launch *ā€¯PackageResourceViewer: Open Resource, open the Java package and look for the syntax files (e.g.Java.sublime-syntax`).
I'm not familiar enough with Java, but it looks to me like class uses the scope meta.class and int uses storage.type.primitive.array. That means, that in your theme you would at least have to change meta or storage. Needless to say that you can be more specific than that.
Using a nice little plugin called ScopeAlways, you can see in the status bar the full scope underlying your cursor (if you have multiple cursors, it just uses the first one). In Sublime Text 2, using the following code:
public class Hello {
public static void main(String[] args) {
System.out.println("Hello World!");
int integer = 13;
}
}
The word class is scoped as storage.modifier.java, whereas int is scoped as storage.type.primitive.array.java (I removed a few unimportant extraneous scopes from each for clarity). So, in your theme, you could have one color for storage.modifier, and another for storage.type, to differentiate between class and int. Be aware, however, that many other keywords will fall under both scopes, so your custom colors won't just highlight those particular words.
Good luck!

Block Check-In on Policy Failure

I've created the check-in policy from this MSDN article as an example (code is just copy / pasted).
This works fine, it appears when I try and do a check-in, however it appears as an warning. So I can ignore it by just pressing Check In again. How can I change the code, as listed in the URL, so that it will return an Error not a warning. I can't see any properties on PolicyFailure to do this.
Essentially I want it to look like the error in this screenshot:
Image Source
EDIT: Here is the exact code that I'm using. Now it is slightly modified from the original source, but not in any massive way I wouldn't have thought. Unfortunately I can't post screenshots, but I'll try and describe everything I've done.
So I have a DLL from the code below, I've added it into a folder at C:\TFS\CheckInComments.dll. I added a registry key under Checkin Policies with the path to the DLL, the string value name is the same as my DLL (minus .dll). In my project settings under source control I've added this Check-In Policy.
It all seems to work fine, if I try and do a check-in it will display a warning saying "Please provide some comments about your check-in" which is what I expect, what I'd like is for it to stop the check-in if any policies are not met, however I would still like the user to be able to select Override if necessary. At the moment, even though there is a warning, if I was to click the Check In button then it would successfully check-in the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace CheckInComments
{
[Serializable]
public class CheckInComments : PolicyBase
{
public override string Description
{
get
{
return "Remind users to add meaningful comments to their checkins";
}
}
public override string InstallationInstructions
{
get { return "To install this policy, read InstallInstructions.txt"; }
}
public override string Type
{
get { return "Check for Comments Policy"; }
}
public override string TypeDescription
{
get
{
return "This policy will prompt the user to decide whether or not they should be allowed to check in";
}
}
public override bool Edit(IPolicyEditArgs args)
{
return true;
}
public override PolicyFailure[] Evaluate()
{
string proposedComment = PendingCheckin.PendingChanges.Comment;
if (String.IsNullOrEmpty(proposedComment))
{
PolicyFailure failure = new PolicyFailure("Please provide some comments about your check-in", this);
failure.Activate();
return new PolicyFailure[1]
{
failure
};
}
else
{
return new PolicyFailure[0];
}
}
public override void Activate(PolicyFailure failure)
{
MessageBox.Show("Please provide comments for your check-in.", "How to fix your policy failure");
}
public override void DisplayHelp(PolicyFailure failure)
{
MessageBox.Show("This policy helps you to remember to add comments to your check-ins", "Prompt Policy Help");
}
}
}
A check-in policy will always return a warning and if your user has permission to ignore them, then they can.
Users can always override the policy. You can query the TFS warehouse to generate a report of users violating the policies and their reasons for the violation if they provided any. Or setup an alert whenever someone ignores these polite warnings.
There is no way to enforce this from the policy itself. Only from a server side plugin, as described by Neno in the post you quoted. Such a server side plugin can be created for 2012 or 2010 as well. The process is explained here.
I just got past that issue by turning on Code Analysis on my project - right click on your project, click properties, go to Code Analysis, select the Configuration drop down and pick "All Configurations", select the "Enable Code Analysis on Build".
Do a build and make sure you have no errors / warnings.
This will get you past any policies requiring code analysis on build.

How to create a ReSharper 8.X Custom Macro that can fetch and process the containing type name

ReSharper 8.X ships with a macro that fetches the "Containing Type Name", but what I want to do is manipulate that name. I'm using this in a Visual Studio 2013 Web API project, and I want a template that takes the class name and builds the URL that has to be called. So, for example, suppose I have this:
public class AnnouncementController : ApiController
{
//Want to put a template here!
[HttpGet]
public HttpResponseMessage GetActiveAnnouncements()
{
/// ...
}
}
now my ReSharper template will look something like this:
/// This sample shows how to call the <see cref="$METHOD$"/> method of controller $CLASS$ using the Web API.
/// https://myurl.mydomain.com/api/$CONTROLLER$/$METHOD$
$Controller$, by convention, is the class name minus the letters 'Controller'. This is because ASP.NET MVC Web API projects expect classes derived from ApiController to end with the string 'Controller',
Since this class is AnnouncementController, the template should output
https://myurl.mydomain.com/api/Announcement/GetActiveAnnouncements
Resharper's Built-In Macros can give me some of what I need, but I want to write a custom macro that fetches the containing type name and chops "Controller" off of it. I would like to do that directly, without storing the containing type name in another parameter.
Also, how do I install this custom macro? I've Googled around, and all I found was a lot of dead links and old walkthroughs written for ReSharper version 7 and below that do NOT work with ReSharper 8.x
After a lot of fighting, here is my solution.
[MacroImplementation(Definition = typeof (ControllerNameMacroDefinition))]
public class ControllerNameMacroImplementation : SimpleMacroImplementation
{
public ControllerNameMacroImplementation([Optional] IReadOnlyCollection<IMacroParameterValueNew> arguments)
{
}
public override HotspotItems GetLookupItems(IHotspotContext context)
{
var ret = "CONTROLLER";
var fileName = GetFileName(context);
if (!fileName.IsNullOrEmpty())
{
//Replace "Controller.cs" in two separate steps in case the extension is absent
ret = fileName.Replace("Controller", "").Replace(".cs", "");
}
return MacroUtil.SimpleEvaluateResult(ret);
}
/// <summary>
/// Returns the filename of the current hotspot context
/// </summary>
private string GetFileName(IHotspotContext context)
{
var psiSourceFile = context.ExpressionRange.Document.GetPsiSourceFile(context.SessionContext.Solution);
return psiSourceFile == null ? string.Empty : psiSourceFile.Name;
}
}
I wanted to do exactly this, but for JavaScript Jasmine tests -- SomethingViewModel.js, with a fixture of SomethingViewModelFixture.js, but wanted to be able to refer to SomethingViewModel in the file. A few slight modifications to the above made it possible.
Unfortunately, there's a ton more things you need to do in order to get your plugin to actually install. Here's a list. I hope it's comprehensive.
NuGet package install JetBrains.ReSharper.SDK, make sure you have the correct version installed!
Copy your Class Library DLL to C:\Users\<you>\AppData\Local\JetBrains\ReSharper\<version>\plugins\<your plugin name>, creating the plugins directory if needed.
You need the plugin Annotations in your AssemblyInfo.cs file:
[assembly: PluginTitle("Your extensions for ReSharper")]
[assembly: PluginDescription("Some description")] -- this is displayed in ReSharper->Options->Plugins
[assembly: PluginVendor("You")]
You need a class in your project that defines the MacroDefinition, as well as the above MacroImplementation
[MacroDefinition("MyNamespace.MyClassName", ShortDescription = "A short description of what it does.", LongDescription = "A long description of what it does.")]
"ShortDescription" - this is displayed in the "Choose Macro" dialog list.
"LongDescription" you'd think this would be in the "Choose Macro" description, but it isn't.
I just added this annotation to the above file.
The file you add the MacroDefinition to needs to implement IMacroDefinition, which has a method (GetPlaceholder) and a property (Parameters) on it. The former can return any string ("a") and the latter can return an empty array.
You can ignore the WiX/NuGet stuff if you want. Just for a local install.
In VS, the ReSharper->Options->Plugins section has some troubleshooting details on why your plugin might not be loading.
Good luck!

Possible to regenerate designer.cs file without Visual Studio?

I have few frequently changeable fields stored in Resources.resx which auto generates the file Resources.designer.cs. It has email addresses, location paths which are to be updated based on needs
Now I would like to make the application usable even for a non developer - Even a lay man must be able to edit the email address & Paths.
Had a thought that if someone edits the .resx file(which is easily editable even in notepad) can I write some .exe code to auto generate the corresponding designer.cs for it?
Thanks for understanding..
If visual studio can do it, you can do it. But I think letting a non-technical person edit an xml file is asking for trouble. What I would do is build a small editing tool which pulls out only those fields you want to change, displays them in a simple form for altering, then writes them back to to the resx before rebuilding the designer.
I have done something similar to this for editing an application.exe.config file so that configurations can be changed without danger of (even a technical person) killing the thing with a typo, which is all too easy.
You could use something like
private void ReadResxFile(string filename)
{
if (System.IO.File.Exists(filename))
{
using (ResXResourceReader reader = new ResXResourceReader(filename))
{
//TODO
}
}
}
public void SaveResxAs(string fileName, string key, string value)
{
try
{
using (ResXResourceWriter writer = new ResXResourceWriter(fileName))
{
writer.AddResource(key, value);
writer.Generate();
}
}
catch (Exception error)
{
throw error;
}
}

Possible C# 4.0 compiler error, can others verify?

Since I don't know exactly what part of it alone that triggers the error, I'm not entirely sure how to better label it.
This question is a by-product of the SO question c# code seems to get optimized in an invalid way such that an object value becomes null, which I attempted to help Gary with yesterday evening. He was the one that found out that there was a problem, I've just reduced the problem to a simpler project, and want verification before I go further with it, hence this question here.
I'll post a note on Microsoft Connect if others can verify that they too get this problem, and of course I hope that either Jon, Mads or Eric will take a look at it as well :)
It involves:
3 projects, 2 of which are class libraries, one of which is a console program (this last one isn't needed to reproduce the problem, but just executing this shows the problem, whereas you need to use reflector and look at the compiled code if you don't add it)
Incomplete references and type inference
Generics
The code is available here: code repository.
I'll post a description below of how to make the projects if you rather want to get your hands dirty.
The problem exhibits itself by producing an invalid cast in a method call, before returning a simple generic list, casting it to something strange before returning it. The original code ended up with a cast to a boolean, yes, a boolean. The compiler added a cast from a List<SomeEntityObject> to a boolean, before returning the result, and the method signature said that it would return a List<SomeEntityObject>. This in turn leads to odd problems at runtime, everything from the result of the method call being considered "optimized away" (the original question), or a crash with either BadImageFormatException or InvalidProgramException or one of the similar exceptions.
During my work to reproduce this, I've seen a cast to void[], and the current version of my code now casts to a TypedReference. In one case, Reflector crashes so most likely the code was beyond hope in that case. Your mileage might vary.
Here's what to do to reproduce it:
Note: There is likely that there are more minimal forms that will reproduce the problem, but moving all the code to just one project made it go away. Removing the generics from the classes also makes the problem go away. The code below reproduces the problem each time for me, so I'm leaving it as is.
I apologize for the escaped html characters in the code below, this is Markdown playing a trick on me, if anyone knows how I can rectify it, please let me know, or just edit the question
Create a new Visual Studio 2010 solution containing a console application, for .NET 4.0
Add two new projects, both class libraries, also .NET 4.0 (I'm going to assume they're named ClassLibrary1 and ClassLibrary2)
Adjust all the projects to use the full .NET 4.0 runtime, not just the client profile
Add a reference in the console project to ClassLibrary2
Add a reference in ClassLibrary2 to ClassLibrary 1
Remove the two Class1.cs files that was added by default to the class libraries
In ClassLibrary1, add a reference to System.Runtime.Caching
Add a new file to ClassLibrary1, call it DummyCache.cs, and paste in the following code:
using System;
using System.Collections.Generic;
using System.Runtime.Caching;
namespace ClassLibrary1
{
public class DummyCache<TModel> where TModel : new()
{
public void TriggerMethod<T>()
{
}
// Try commenting this out, note that it is never called!
public void TriggerMethod<T>(T value, CacheItemPolicy policy)
{
}
public CacheItemPolicy GetDefaultCacheItemPolicy()
{
return null;
}
public CacheItemPolicy GetDefaultCacheItemPolicy(IEnumerable<string> dependentKeys, bool createInsertDependency = false)
{
return null;
}
}
}
Add a new file to ClassLibrary2, call it Dummy.cs and paste in the following code:
using System;
using System.Collections.Generic;
using ClassLibrary1;
namespace ClassLibrary2
{
public class Dummy
{
private DummyCache<Dummy> Cache { get; set; }
public void TryCommentingMeOut()
{
Cache.TriggerMethod<Dummy>();
}
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
}
}
Paste in the following code in Program.cs in the console project:
using System;
using System.Collections.Generic;
using ClassLibrary2;
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
Dummy dummy = new Dummy();
// This will crash with InvalidProgramException
// or BadImageFormatException, or a similar exception
List<Dummy> dummies = dummy.GetDummies();
}
}
}
Build, and ensure there are no compiler errors
Now try running the program. This should crash with one of the more horrible exceptions. I've seen both InvalidProgramException and BadImageFormatException, depending on what the cast ended up as
Look at the generated code of Dummy.GetDummies in Reflector. The source code looks like this:
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
however reflector says (for me, it might differ in which cast it chose for you, and in one case Reflector even crashed):
public List<Dummy> GetDummies()
{
List<Dummy> policy = (List<Dummy>)this.Cache.GetDefaultCacheItemPolicy();
TypedReference CS$1$0000 = (TypedReference) new List<Dummy>();
return (List<Dummy>) CS$1$0000;
}
Now, here's a couple of odd things, the above crash/invalid code aside:
Library2, which has Dummy.GetDummies, performs a call to get the default cache policy on the class from Library1. It uses type inference var policy = ..., and the result is an CacheItemPolicy object (null in the code, but type is important).
However, ClassLibrary2 does not have a reference to System.Runtime.Caching, so it should not compile.
And indeed, if you comment out the method in Dummy that is named TryCommentingMeOut, you get:
The type 'System.Runtime.Caching.CacheItemPolicy' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Why having this method present makes the compiler happy I don't know, and I don't even know if this is linked to the current problem or not. Perhaps it is a second bug.
There is a similar method in DummyCache, if you restore the method in Dummy, so that the code again compiles, and then comment out the method in DummyCache that has the "Try commenting this out" comment above it, you get the same compiler error
OK, I downloaded your code and can confirm the problem as described.
I have not done any extensive tinkering with this, but when I run & reflector a Release build all seems OK (= null ref exception and clean disassembly).
Reflector (6.10.11) crashed on the Debug builds.
One more experiment: I wondered about the use of CacheItemPolicies so I replaced it with my own MyCacheItemPolicy (in a 3rd classlib) and the same BadImageFormat exception pops up.
The exception mentions : {"Bad binary signature. (Exception from HRESULT: 0x80131192)"}

Resources