How to use GetExtentOfWord in the new IAsyncQuickInfoSource API? - c#

I am writing a C# extension for Visual Studio and I am trying to use the new API for QuickInfos: https://github.com/Microsoft/vs-editor-api/wiki/Modern-Quick-Info-API. I am prototyping based on this sample: https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/AsyncQuickInfo. It works fine as long as I don't change it.
The sample is only focusing on the whole line:
var line = triggerPoint.Value.GetContainingLine();
However, I need to get the hovered word. In the old API, I was using this and it was working fine:
var navigator = provider.NavigatorService.GetTextStructureNavigator(buffer);
var hoveredWord = navigator.GetExtentOfWord(triggerPoint.Value);
Unfortunately, Visual Studio will freeze as soon as I call GetExtentOfWord with the new API!!! More precisely, I will pass a few times and then it will freeze (quite shortly).
What should do I to be allowed to get the hovered word extent with the new IAsyncQuickInfoSource API?
Thanks!

Related

Setting Outlook automatic reply signature using C# is only partly working

I am trying to set the default Outlook signature for both new messages and replies using C#.
Everything is working as expected for new messages (meaning that when I create a new message in Outlook, I can see the default signature), but nothing shows up when I reply to messages (or forward them).
This seems weird for two reasons:
In Outlook, I can see in the signature manager that that the default signature for replies is set properly. If I select another signature and select "Auto_Signature" again, everything starts working as expected, so it's not a problem with the signature itself.
The new messages signature is set the same way as the replies signature and that one works.
Here is the code that I am using to set the default signatures:
using Microsoft.Office.Interop.Word;
private void ApplyDefaultSignatureExecuted(object? obj)
{
var signaturesFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft\\Signatures");
var fileName = Path.Combine(signaturesFolder, "Auto_Signature.htm");
using (var writer = new StreamWriter(fileName))
{
writer.WriteLine("<html><body>");
writer.WriteLine("<div><p><i></span></b></p></div>");
writer.WriteLine(HttpUtility.HtmlEncode("Signature that was generated via C#"));
writer.WriteLine("</i></p><p><b><span style='font-size:24.0pt'>");
writer.WriteLine(HttpUtility.HtmlEncode("Name goes here"));
writer.WriteLine("</span></b></p></div>");
writer.WriteLine("</body></html>");
}
Application oWord = new Application();
EmailOptions oOptions = oWord.Application.EmailOptions;
oOptions.EmailSignature.NewMessageSignature = "Auto_Signature";
// This is the line that should be setting the auto-reply signature
oOptions.EmailSignature.ReplyMessageSignature = "Auto_Signature";
//Release Word, not sure if this has any effect as I get the same results with or without those lines
System.Runtime.InteropServices.Marshal.ReleaseComObject(oOptions);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord);
}
And here are some screenshots to go along with my explanation:
Reply - Signature does not appear automatically
Signature manager - Default signatures are set properly by C#, and changing to another one and back makes everything work as it should
New message - Signature appears automatically
According to everything I have read, this should be working since setting the signature for new message and replies is the same code, but it's not. I am using Office 365 and I don't mind switching libraries if that solves my issues.
I got it working by simply changing the line
oOptions.EmailSignature.ReplyMessageSignature = "Auto_Signature";
To
oOptions.EmailSignature.ReplyMessageSignature = oOptions.EmailSignature.NewMessageSignature;
Everything is now working exactly the same for replies and forwards as it does for new messages.

Anyone know how to call a feature file fromthe middle of the code - Specflow & c#

Good morning / Afternoon
I have a main class that runs a lot of specific items that include calls to DB, etc.
In the middle of the code I want the code to run a list of specific feature files (specflow) but with all the previous parameters included
I have tried everything but I cannot seem to get it to work.
Anyone got some suggestions?
Thanks
Part of code attached
foreach (string element in Features)
{
DriversPage drivers = new DriversPage(mainRun, steps);
mainRun.TestRunNumber = dataBases.getRunNumberFromDB();
steps.TestRunNumber = mainRun.TestRunNumber; steps.InitializeStep();
drivers.InitializeDriver(element); steps.TerminateStep();
steps.UpdateCollections();
//CALL FEATURE FILE HERE!!!!
steps.UpdateCollections();
}

Rotativa ActionAsPdf() Very Slow

Using Rotativa 1.6.4 from NuGet and have noticed the following issue using the code below.
ActionAsPdf hangs randomly for indeterminate amount of time.
Code below that is hanging:
var pdfResult = new ActionAsPdf("Report", new {id = Request.Params["id"]})
{
Cookies = cookieCollection,
FormsAuthenticationCookieName = FormsAuthentication.FormsCookieName,
CustomSwitches = "--load-error-handling ignore"
};
Background info that may help:
The customSwitches is in use to ignore a documented issue calling wkhtmltopdf.exe using the ActionAsPdf, but it does not suppress errors in the code only in the wkhtmltopdf call.
Observations, usage and testing:
It works but when running the application (whether or not stepping through code), it can be anywhere from 10 seconds up to about 4 minutes between hitting the pdfResult = new ActionAsPdf and finally entering into the "Report" action being called. Can't discern anything actually happening in the output window of Visual Studio, no errors are being thrown that I have found. Just random slow transition into the Reports() action.
I can run the Reports() action directly via URL and it never slows like this and is quite fast for PDF generation. I am running it using the ActionAsPdf to obtain the binary to save to file system and send via email, which is the prescribed method of doing so for this library.
The behavior exists on both a local Windows 10 dev box and a remote Server 2008R2 Test box. .Net 4.5.1 on both boxes, default IIS on each.
Questions I have:
Any idea on what might cause this slow down and how to remedy it?
I ended up using UrlAsPdf() instead of ActionAsPdf() and it works. Seems there may be some issues with the ActionAsPdf() and I have filed a bug with Rotative project on GitHub. The ActionAsPdf() is still marked as beta, so hopefully it get's fixed in future versions or by the community.
In my case, I had to do few more tweaks along with using UrlAsPdf(). I have narrowed down the issue to the cookie collection that I was adding. So I tried just adding the cookie that I needed, and the issue was resolved. Following is the sample code that I have used.
var report = new UrlAsPdf(url);
Dictionary<string, string> cookieCollection = new Dictionary<string, string>();
foreach (var key in Request.Cookies.AllKeys)
{
if (Crypto.Hash("_user").Equals(key))
{
cookieCollection.Add(key, Request.Cookies.Get(key).Value);
break;
}
}
report.Cookies = cookieCollection;
report.FormsAuthenticationCookieName = FormsAuthentication.FormsCookieName;

microsoft.interop.selection text

Before asking my question I would like to describe briefly background of my problem: I'm developing ms word COM addin on C# and I need to handle user's text selections. Now I'm able to catch selection event - it's look like
Microsoft.Interop.Word._Application app;
app = (Word._Application )Application; // Application object comes on addin's connection
app.Application.WindowSelectionChange+=
new Word.ApplicationEvents4_WindowSelectionChangeEventHandler(selChange);
///
void selChange(Word.Selection selection){
MessageBox.Show(selection.Text); // this is my problem, Text property is not available
}
// property Text doesn't exist,but documentation tells that it exists. I suspect, that this property is not available for ms word 2007 - in the documentation only 2003,2010 versions are mentioned. But how I can do something like selection.getSelectedText()? I tryed to play with selection.Rows, selection.Rows[0],selection.Words,selection.Words[0] - no success.
According to the documentation, the Selection.Text property should be available for Word 2007 as well. I made a small sample implementation of your case to test it, and I cannot make it fail on Word 2010 and 2013 at least:
var wordApplication = new Application() { Visible = true };
wordApplication.Documents.Add();
wordApplication.WindowSelectionChange += delegate(Selection mySelection) { Console.WriteLine(mySelection.Text); };
So, I suggest you check that you have included the right namespaces and that the Selection interface you are using are actually the one from the Microsoft.Office.Interop.Word namespace.

How can I send input to Visual Studio using Windows API

I am trying to develop a util (using system-hook) for that works like an expander (user selects some text and presses a hotkey and it is expands). It should work with Visual Studio.
I want to implement this using Windows API because I want to develop an app that works globally with any application (whether you're using VS, or wordpad, you should get the same functionality).
I've been able to do this successfully with notepad, wordpad, etc. using EM_ GETSEL and EM_REPLACESEL messages. But these APIs are not working with Visual Studio, or ms word.
What APIs should I use to be able to
1. Detect what text is selected.
2. Send input to the editor.
I am programming in C#. If you must know what I am trying to do... I am trying to make a universal port of ZenCoding that works on any editor. So all help will be appreciated.
For part 2 you could try using Windows Input Simulator which is an open source project I've just released to Codeplex to wrap the Win32 SendInput. Instead of SendKeys which just simulates text input, you can actually simulate real key strokes and complex chords to the active window.
In your case, if the user can perform the task with the Keyboard, this project will help you, otherwise you'd need to find another solution.
Hope this helps.
Why don't you use a System.Windows.Forms.SendKeys class for simulating keyboard input from user?
You can use:
SendKeys.SendWait("^C"); //CTRL+C
var selectedText = Clipboard.GetText();
var newText = Replace(selectedText);
SendKEys.SendWait("^V"); //CTRL+V
You can use WPF's Automation functionality, encapsulated in these two namespaces:
System.Windows.Automation
System.Windows.Automation.Provider
As an example, this is a method for finding an automation target element (e.g. a typical win control):
public static AutomationElement FindElement(AutomationElement context, PropertyCondition[] conditions)
{
// if no conditions, there's no search to do: just return the context, will be used as target
if (conditions == null)
{
return (context);
}
// create the condition to find
System.Windows.Automation.Condition condition = null;
if (conditions.Length <= 0)
{
throw (new ArgumentException("No conditions specified"));
}
else if (conditions.Length == 1)
{
condition = conditions[0];
}
else
{
AndCondition ac = new AndCondition(conditions);
condition = ac;
}
// find the element
CacheRequest creq = new CacheRequest();
creq.TreeFilter = Automation.ControlViewCondition;
using (creq.Activate())
{
AutomationElement e = AutomationContext(context);
AutomationElement target = e.FindFirst(TreeScope.Subtree, condition);
return (target);
}
}
Whatever you try, be absolutely sure to try it, ASAP, with Visual Studio 2010 beta 2. The editor has largely been rewritten, and hacks that work with an earlier version should be tested again.

Categories