Visio Add-in Experts for Visual Studio - c#

I was wondering if anybody had any experience with dealing with managed code add-ins specifically for Visio in a .NET project. I am messing around with one and am trying to remove hyperlinks from a Shape object. Deleting them works fine and if the user saves then all works well. The problem arises when the user does not save and is prompted by Visio, before close, that there are unsaved changes and wants to know what the user wants to do. If the user selects "Don't save" and just tries to exit, the Visio application crashes with an unhandled Win32 exception that I have traced back to an Exception code: 0xc0000005 in the Windows Event Viewer. This turns out to be an "Access Violation Error". I have found the issue to be a line of code that calls the Delete method on the Hyperlinks collection of a shape (Example below). Anybody know what is going on here? Is this a MS bug that I just can't find on the Google? Hope I have enough information for you guys here. Did not think I needed to post a bunch of code since I have found only this line of code produces the exception when Visio tries to exit after a do not save. I have found this to produce the exact error with versions 12 and 14 of the Microsoft.Office.Interop.Visio.dll.
internal static Nullable<Boolean> DeleteFirstHyperlink(Shape shape) {
if(true){ //a condition to pass
shape.Hyperlinks.get_ItemU(0).Delete();
return true;
}
else{
return false;
}
}

I think you might be deleting hyperlinks from a "before shape deleted" event handler? I this case, you should not do that. Instead, you can remember what to delete and delete it afterwards in "no events pending" / "shape deleted" event handler.. Or it may be some similar case.
Check here: https://msdn.microsoft.com/en-us/library/office/ff767512.aspx
After Visio has fired the MustFlushScopeBeginning event, client programs should not call Visio methods that have side effects until the MustFlushScopeEnded event is received. A client can perform arbitrary queries of Visio objects when Visio is between the MustFlushScopeBeginning event and MustFlushScopeEnded event, but operations that cause side effects may fail.
If this is not the case, then probably one would need a complete example illustrating the problem (full source code illustrating the problem) to figure out what is going on.
I mean, normally you can delete hyperlinks without any issues.

Related

Microsoft Excel is waiting for another application to complete an OLE action Error

I frequently receive ok-only prompts while automating add-ins in Excel, stating that Microsoft Excel is waiting for another application to complete an OLE action Error. How to use Interop.dll to show a custom message and handle this error programmatically. Before receiving the promptenter link description here
While You possibly can catch these exceptions depending on your automation framework and do something with it - these type of errors typically comes from not closing the files properly when changing from one to another.
Make sure you dispose all that can be disposed and close all which can be closed in reverse order obviously and it should go away.
If You need more details do post your code for opening and closing looks like a bug there which will make it not coming up.
You do not technically have to use interop, could you consider using a more modern package for interacting with excel?
If you are using google drive / file stream then this may be the problem. Turn off "Real Time Presence in Microsoft Office" then the messages go away.

Finding some terminologies for doing R&D

I am here because I have a program and some features in my mind.
But I am not sure what these features are called in programming terms. So I am unable to even do a proper google search regarding the same. I am keen to identify what this is called, so I can progress my Analysis and Research.
I have developed a program, with C# and Windows Forms. Currently it interfaces with YouTube API and monitors the chat. I am also raising some events, when chat messages arrive and when the message follows a certain format/syntax. Everything is working fine so far.
What I want to do is:
If someone using my software, who has access to just the binaries. But want to write their own logic, which handles some of the events I am raising. How do they do that?
I want the user to write their own program/class, put it in a specific folder. I will expect it to have a Start() and End() method. Inside the methods, they can write the code to subscribe to any event of their choice and do what they need to.
I already have written code inside my main loop, which will loop through the folder which is supposed to contain the user programs, and tries to invoke the Start/End method of their programs/classes.
For me, as the original author of the project, I can just go ahead and start writing the code inside the folder. Once I build and execute. Everything works fine. The main program triggers the Start/End inside the program/class that I added. And the events are also handled fine.
But how about someone using my software, who wants to handle it's events, without having to re-compile my code. How do they do that?
You have the following options
Option 1
Create a template project with all required references and a code file (.cs) with the Start() / End() methods.
Add comments to the start() / end() methods or add a code sample of how they can work with the additional events.
The project should compile fine without any source code for your main project.
If you expect the users to use Visual Studio Code, give them instructions to compile using VS code.
If they are going to use any text editor, you need to provide them with a msbuild command line to compile their code.
Finally they can put the .cs code file in the specific folder along with your main project binary and try it out.
Option 2
The above option will work only if your users are also programmers.
If they are semi-techies, you could provide a simpler format for them to provide the additional events.
For example, create a json or xml format where they can specify the event name and how they want to handle it - either a script or choose from some options. For example -
{
"myevents": [
{
"event": "chatUpvote",
"handler": "ThankYouHandler"
},
{
"event": "chatDownvote",
"handler": "TellMeMoreHandler"
}]
}

File Locked Updated Sharepoint Document

I'm trying to do some changes to the properties of the documents that users edit in a Sharepoint 2010 Document Library progammatically using an Event Handler. At the moment, I'm trying with the event ItemCheckedIn. The problem comes when I execute the following instruction:
item.File.Update();
It gives me an exception saying that the document is locked by user XXX.
Am I updating the properties in the wrong event? How can I avoid this exception?
Thank you in advance.
Try using
item.SystemUpdate()
instead
Microsoft Office Word is issuing a lock request on documents by default and it is different than 'Checked Out' state.
'Lock' is release only after document is closed by Word. While 'Check Out' can be performed via Word or web interface and it would remain such until explicitly requested to 'Check In'.
As previous comment suggest, the best remedy is to to use in your code:
item.SystemUpdate(false) as that would not obey to 'Lock' state and save any changes done via Event handler code.

How to Show the Content of a Variable Which is in a Class Library In A Form Or Console?

I have a C# solution which contains a project and a class library written by somebody else. The class library gets GPS data via wifi. The project shows the processed data on a map. Now, I want to see the contents of some variables in the class library in real time for the sake of debugging.
I tried to use
System.Diagnostics.Debug.Write(value)
without success. It seems it does not do anything.
Also I tried "MessageBox.Show(value.ToString())" which was good but it stopped the wifi reading and interrupted the program as I needed to press OK button each time that it showed up.
Moreover, I added a windows form (which contained a textBox) to the class library to print the data in the textBox, however, when I wrote:
Form1.textBox1.Text = value.ToString()
It gives me this error:
Error 3 'MapNMEA.Form1.textBox1' is inaccessible due to its protection level C:\Users\john\Documents\Visual Studio 2010\Projects\new ver of map purecom\MapExplorer\MapExplorer\MapNMEA\MapNMEA\SerialPort.cs 184 27 MapNMEA
"MapNMEA" is the name of the class library. Also "MapExplorer" is the name of both solution and the project. "SerialPort.cs" is a file inside the class library in which I wrote the above code.
My question is how to show the content of those variable (they are 3,4 variables) in real time and this act should not stop the wifi reading. I need to do this as an electrician who does not know much about programming wants to check whether a GPS device sends the data to my computer correctly or not.
UPDATE 1: Actually I noticed that System.Diagnostics.Debug.Write(value) is working but as there was too many warning messages showing up in the debug window, I did not noticed it. Now, if somehow I could remove (or hide) other (warning) messages, I would see only my desired output. Do you know?
Debug.Write should be fine if you attach a listener first (Debug.Listeners.Add( new _a_listener_type() )).
Also, you should probably be aware of the AutoFlush property on the Debug class which determines whether or not Flush is automatically called.
Debug.Write should work - by default it will write to the 'Debug' window in Visual Studio if you have the debugger attached. Are you sure you're looking in the right place?
If you want to use the form approach, you need to keep track of the instance of the form which is open, and give it a public method. For example:
public void WriteDebug(string message) {
TextBox1.Text += message + Environment.NewLine;
}
Then you can call formInstance.WriteDebug(message);.
Do you run debug build? Also your code with textbox does not work, because textBox1 is non-public
I think you may not be searching the right location: Is there something preventing you from debugging on a PC first before going to a target? If not, the you should probably use the traditional way: put spies on variables, use your IDE (Visual Studio) to watch them and so on.
If you actually NEED to run on target without advanced debug tools, then you might want to take a look at some easier solutions:
log them to a text file (append or replace, whatever you need), then have a viewer opened at hand
make another non-modal form with a textbox, and call a form2.writeDbgTextBox(String) every time you need to refresh
Be sure to remove this code on release (eg. by putting them in a #if DEBUG section)
And whatever happens, DO NOT try to write to an existing Message box! they are made to pop up and close, not to interact with your code.

Excel automation via OLE - suppressing / catching dialog box errors?

I refresh Excel 2007 data connections via a C# program and OLE. Most of the work is done by a single Workbooks.RefreshAll() statement.
As is the nature of refreshing spreadsheets, various things can go wrong. During the refresh process, the program can give dialog box error messages about "Data cannot be read from file '|'", and a message about "Overlapping pivottable reports". Both of these are fatal, and I should be able to catch these errors, and exit my program with an error.
Unfortunately, I don't seem to be able to catch these problems, and instead my automated program sits until I come along and hit enter on the dialog.
Does anyone know if it's possible to programmatically catch the errors shown in excel dialog boxes, instead of having them displayed to the user?
Your best bet is to set the Application.DisplayAlerts property to False. That is, assuming that your Excel.Application object variable is named "xlApp", all you'd have to do is the following:
xlApp.DisplayAlerts = false;
Note that this will cause the default response to be taken for each dialog box, which is normally what you would want. (There's no good way around this. Leaving DisplayAlerts = True and using SendKeys might be your only other option, but would be ugly and very error prone.)
Since you are making this call via OLE Automation, this call is cross-process, and, therefore, the DisplayAlerts setting will persist until you change it. (If called in-process, via VBA, it is switches back to to true automatically when the routine completes. The same behavior probably applies for a VB.NET or C# add-in called via a CommandBar or Ribbon control, but one would need to test to be certain.)

Categories

Resources