I have a custom EventSource that I am using to log an ETW event:
[EventSource(Name = "MyEventSource")]
public class MyEventSource : EventSource
{
[Event(1, Message = "Test", Level = EventLevel.Informational)]
public void Run(long fundId, DateTime date)
{
if (IsEnabled()) WriteEvent(1, fundId, date);
}
public static MyEventSource Log = new MyEventSource();
}
I have added my EventSource details to the Markers tab of the Advanced Settings dialog (from the Analyze menu in VS 2013) with it's correct Name and Procider GUID (I know these are correct as I can see the events in PerfView) and logging level = Everything.
When I run Concurrency Visualizer from Visual Studio I am unable to see my custom EventSource events though. However I can see other event sources (eg. some from the System.Collections.Concurrent provider)
Any help greatly appreciated, thanks.
Here is he answer from Zelestor
I worked this out in the end - the DateTime type is not supported by
EventSource
Related
On my development machine I have the FormInitializing and FormShowing events firing before RibbonLoad. I created a setup package in VS 2010 and installed on a vanilla Windows 7 Ultimate with Outlook 2010 installed.
The addin wasn't appearing on my meeting request form. So I setup remote debugger and to my astonishment the RibbonLoad is firing before the two form events mentioned above. A null exception is being throw b\c the code in the RibbonLoad relies on the FormRegion already being loaded. Can anyone offer any insight?
There is no defined order for certain Outlook events - the Ribbon UI and the Inspector UI are completely different components, despite them both being display in the same window. The Outlook runtime may trigger Ribbon and Inspector events in different orders. It would be your job to synchronize the two events (RibbonLoad and FormInitializing) if you need some initialization done. You cannot assume that the ordering will always be the same.
I notice this same behavior when ThisAddIn.Startup fires before ThisAddIn.CreateRibbonExtensibilityObject, but sometimes after depending on how Outlook triggers the sequencing. You can just use a static variable with sync locking to ensure your initialization code is only triggered once.
Here is an example I used to synchronize the Startup event with the RibbonLoad event:
public partial class ThisAddIn
{
static bool formInitialized = false;
static readonly object padLock = new Object();
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
lock(padLock) { if (!formInitialized ) { InitializeForm(); } }
// startup code
}
private void InitializeForm()
{
// init code
formInitialized = true;
}
protected override IRibbonExtensibility CreateRibbonExtensibilityObject()
{
lock(padLock) { if (!formInitialized) InitializeForm(); }
// Create ribbon UI
}
}
Initial Situation:
We are developing an Add-in for Outlook 2010 in C# with VS.NET 2010 based on Framework 4.0, VSTO, DevExpress WinForm Controls. In Designer we have a Ribbon with a RibbonTab, then a RibbonGroup then a RibbonButton. We're consuming WebServices from within this Outlook Add-in.
Objective:
We need to enable/disable the RibbonButtons when the WebService is available/unavailable (from/out of the code)
we've found the following links:
Links
Ribbon Object Model Overview: http://msdn.microsoft.com/en-us/library/bb608623.aspx
Ribbon Overview: http://msdn.microsoft.com/en-us/library/bb386097.aspx
Walkthrough: Updating the Controls on a Ribbon at Run Time: http://msdn.microsoft.com/en-us/library/bb608628.aspx
After hours of trying to figure out how to implement this we deciced to post/ask this question here on SO. Does anybody have a sample code? We tried the IRibbonExtensibility and CreateRibbonExtensibilityObject => we added the RibbonTab, Group and Button and added a subscription to the Click Event => The Event is fired but not handled (in button_Click(...) => System.Diagnostics.Debugger.Break() is not breaking the code execution)
Thanks!
Christian
You'll want to invalidate the Ribbon at a fairly frequent rate in order to refresh the visibility of each tab/button. You can do this by subscribing to the Click event (as you've done) and then calling RibbonObject.Invalidate();. Then add a getEnabled="yourTestFunction" parameter to each button, with public bool yourTestFunction(Office.IRibbonControl control) (Defined in the Ribbon.cs file) returning whether the web service is available or not.
Keep in mind if the web service is down, each click could hang your application for the amount of time you set on your timeout in the web service check
Edit:
Just realized the _Click event isn't mapped in the Excel COM library, so here's a bit of code that will run each time the cell selection is changed (not as frequent as every click, but hopefully good enough).
ThisAddIn.cs:
public static Excel.Application e_application;
public static Office.IRibbonUI e_ribbon;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
e_application = this.Application;
e_application.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(e_application_SheetSelectionChange);
}
void e_application_SheetSelectionChange(object Sh, Excel.Range Target)
{
e_ribbon.Invalidate();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
e_application.SheetSelectionChange -= new Excel.AppEvents_SheetSelectionChangeEventHandler(e_application_SheetSelectionChange);
e_application = null;
}
Ribbon1.cs:
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
ThisAddIn.e_ribbon = ribbonUI; //Add this line
}
and
public bool getEnabledTest(Office.IRibbonControl control)
{
//Whatever you use to test your Web Service
//return false;
}
Ribbon1.xml:
<button id="WebService" label="Use The Web Service" onAction="executeWebService" getEnabled="getEnabledTest" />
The following article titled Adding Custom Dynamic Menus to the Office Fluent User Interface will point you in the right direction.
The below is an example of a dynamically created menu, you can modify the tutorial to fit your particular need.
ok, thanks for the tips. Finally i solved it like this:
i declared a static ribbon object like:
public static RibbonIet ribbon {get; set; }
in the load event of the Ribbon i assign the Ribbon (this) like:
Session.Common.ribbon = this;
now i can control the RibbonButton like:
Session.Common.ribbon.buttonCreateIncident.Enabled = true;
Since the webService call is running in a seperate thread, i had to use a MethodInvoker to change enable/disable the buttons. it goes like this:
If (InvokeRequired)
{
Invoke(new MethodInvoker(() => Session.Common.ribbon.buttonCreateIncident.Enabled = true));
}
maybe this is of help for someone else.
I've been trying to get a simple visual studio add in working. I just want to run a function on a file when a document is saved, but for some reason the event is not firing for web site solutions. It works as expected on normal projects.
Here is my code so far:
DocumentEvents docEvents;
Events events;
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
events = _applicationObject.Events;
docEvents = events.DocumentEvents;
docEvents.DocumentSaved += new _dispDocumentEvents_DocumentSavedEventHandler(docEvents_DocumentSaved);
}
void docEvents_DocumentSaved(Document document)
{
//do something here (doesn't reach this)
}
Any help would be appreciated, or even a pointer to a simple example project where the DocumentSaved event is working on web site solutions.
EDIT: I'm using Visual Studio 2010
Look at this (updated):
https://gordon-breuer.de/unknown/2010/08/19/visual-studio-2010-extension-unicode-converter-1-0-with-tutorial.html
It seems that you have to register your add id for handling certain file types.
I made a simple reusable workflow in SharePoint Designer. Which sends an email and then sets the WF status to "Completed".
Imported in Visual Studio 2010.
I added a CreateTask1 before the email activity in Visual Studio's version and then redeployed it.
Now I expect the workflow to be complete when the task is completed. How ever the workflow still sets to complete once the email is sent.
Any ideas what am I missing here please?
Thanks in advance,
You will need to add an OnTaskChanged activity after your CreateTask1. Wrap that inside of a while activity. Then, you have to check the status of the task in your code.
Here is the code behind:
public bool taskNotComplete = true;
public SPWorkflowTaskProperties onTaskChanged1_AfterProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
private void OnTaskChanged(object sender, ExternalDataEventArgs e)
{
if (onTaskChanged1_AfterProperties1.PercentComplete == 100)
{
// set the while activity condition field
this.taskNotComplete = false;
}
}
In Java, you can use System.out.println(message) to print a message to the output window.
What's the equivalent in Visual Studio ?
I know when I'm in debug mode I can use this to see the message in the output window:
Debug.WriteLine("Debug : User_Id = "+Session["User_Id"]);
System.Diagnostics.Trace.WriteLine("Debug : User_Id = "+Session["User_Id"]);
How can this be done without debugging in Visual Studio?
The results are not in the Output window but in the Test Results Detail (TestResult Pane at the bottom, right click on on Test Results and go to TestResultDetails).
This works with Debug.WriteLine and Console.WriteLine.
The Trace messages can occur in the output window as well, even if you're not in debug mode.
You just have to make sure the the TRACE compiler constant is defined.
The Trace.WriteLine method is a conditionally compiled method. That means that it will only be executed if the TRACE constant is defined when the code is compiled. By default in Visual Studio, TRACE is only defined in DEBUG mode.
Right Click on the Project and Select Properties. Go to the Compile tab. Select Release mode and add TRACE to the defined preprocessor constants. That should fix the issue for you.
This whole thread confused the h#$l out of me until I realized you have to be running the debugger to see ANY trace or debug output. I needed a debug output (outside of the debugger) because my WebApp runs fine when I debug it but not when the debugger isn't running (SqlDataSource is instantiated correctly when running through the debugger).
Just because debug output can be seen when you're running in release mode doesn't mean you'll see anything if you're not running the debugger. Careful reading of Writing to output window of Visual Studio? gave me DebugView as an alternative. Extremely useful!
Hopefully this helps anyone else confused by this.
For me this was the fact that debug.writeline shows in the Immediate window, not the Output. My installation of VS2013 by default doesn't even show an option to open the Immediate window, so you have to do the following:
Select Tools -> Customize
Commands Tab
View | Other Windows menu bar dropdown
Add Command...
The Immediate option is in the Debug section.
Once you have Ok'd that, you can go to View -> Other Windows and select the Immediate Window and hey presto all of the debug output can be seen.
Unfortunately for me it also showed about 50 errors that I wasn't aware of in my project... maybe I'll just turn it off again :-)
To write in the Visual Studio output window I used IVsOutputWindow and IVsOutputWindowPane. I included as members in my OutputWindow class which look like this :
public class OutputWindow : TextWriter
{
#region Members
private static readonly Guid mPaneGuid = new Guid("AB9F45E4-2001-4197-BAF5-4B165222AF29");
private static IVsOutputWindow mOutputWindow = null;
private static IVsOutputWindowPane mOutputPane = null;
#endregion
#region Constructor
public OutputWindow(DTE2 aDte)
{
if( null == mOutputWindow )
{
IServiceProvider serviceProvider =
new ServiceProvider(aDte as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
mOutputWindow = serviceProvider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow;
}
if (null == mOutputPane)
{
Guid generalPaneGuid = mPaneGuid;
mOutputWindow.GetPane(ref generalPaneGuid, out IVsOutputWindowPane pane);
if ( null == pane)
{
mOutputWindow.CreatePane(ref generalPaneGuid, "Your output window name", 0, 1);
mOutputWindow.GetPane(ref generalPaneGuid, out pane);
}
mOutputPane = pane;
}
}
#endregion
#region Properties
public override Encoding Encoding => System.Text.Encoding.Default;
#endregion
#region Public Methods
public override void Write(string aMessage) => mOutputPane.OutputString($"{aMessage}\n");
public override void Write(char aCharacter) => mOutputPane.OutputString(aCharacter.ToString());
public void Show(DTE2 aDte)
{
mOutputPane.Activate();
aDte.ExecuteCommand("View.Output", string.Empty);
}
public void Clear() => mOutputPane.Clear();
#endregion
}
If you have a big text to write in output window you usually don't want to freeze the UI. In this purpose you can use a Dispatcher. To write something in output window using this implementation now you can simple do this:
Dispatcher mDispatcher = HwndSource.FromHwnd((IntPtr)mDte.MainWindow.HWnd).RootVisual.Dispatcher;
using (OutputWindow outputWindow = new OutputWindow(mDte))
{
mDispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
outputWindow.Write("Write what you want here");
}));
}