MS Project VSTO: Closing MS Project causes it to hang indefinetely - vsto

I have replicated this issue in both Project 2010 and 2013.
I developed a VSTO addin, using Visual Studio 2010. In this addin, I have exposed a COMVisible method.
I also have a different (non .NET) application, which then instantiates the Project COM object, searches for my addin and calls the method that I marked as COMVisible.
This causes Project to open a "new" Project file and write something to it.
This non-.NET application, after calling the COM method in my addin, stops execution (without closing MS Project).
I then close the newly created Project (not MS Project, just the file). Everything is fine; however, when I try to close MS Project, it hangs indefinitely. In the Task Manager, it is still shown as "Running" and clicking on the MS Project window brings up a "Switch To", "Retry", "Cancel" dialog, informing me that some other application is busy...
Surprisingly, if I choose to NOT close the newly created Project file, and simply close the MS Project window, it closes normally.
What might be going on here?

Ok, after much investigation, I found the answer to the problem. Basically the COM class exposed from my VSTO Addin needs to inherit "StandardOleMarshalObject".
The reason for this is because the COM method in my Addin was accessing the Project Object Model on a secondary thread (the thread of the calling application). This is a big no no. Deriving from that class marshals all call on that secondary thread to the primary UI thread, thus fixing the problem.

Related

VB.net - Form won't show

My problem concern an application which is currently running in production since 6 months. But last week, one user reported me this :
Above all, this application is a complement to Outlook, which allows users to create, edit and delete tickets through a new tab in the ribbon.
When this user clicks on a button (Create), a window is supposed to appear. In my code, this window is used in two places, one to create the ticket and the other to edit the ticket. When the user wants to edit a ticket, this window appears without problem. But just to create, he won't appear.
I call the window like this for creating :
Dim oForm1 As Create_form
oForm1 = New Create_form(Nothing)
oForm1.Show()
And like this for editing :
Dim oForm1 As Create_form
oForm1 = New Create_form(ticket)
oForm1.Show()
And here is the constructor :
Public Sub New(ticket As Ticket)
InitializeComponent()
MaximizeBox = False
actualTicket = ticket
Init_List()
Init_Fields()
End Sub
I have looked for solutions on the Internet, but it seems I am the only one with this problem. This code worked for this person until last week without any change.
One possibility I thought about is the Microsoft redistributable and the Outlook version (Developed and tested on Outlook 2016, used on Outlook 2013...).
Any ideas ?
Thanks for your help !
Ps : Please excuse my more than average English
First of all, make sure your add-in is enabled and running in Outlook.
Microsoft Office applications can disable VSTO Add-ins that behave unexpectedly. If an application does not load your VSTO Add-in, the application might have hard disabled or soft disabled your VSTO Add-in.
Hard disabling can occur when a VSTO Add-in causes the application to close unexpectedly. It might also occur on your development computer if you stop the debugger while the Startup event handler in your VSTO Add-in is executing.
Soft disabling can occur when a VSTO Add-in produces an error that does not cause the application to unexpectedly close. For example, an application might soft disable a VSTO Add-in if it throws an unhandled exception while the Startup event handler is executing.
When you re-enable a soft-disabled VSTO Add-in, the application immediately attempts to load the VSTO Add-in. If the problem that initially caused the application to soft disable the VSTO Add-in has not been fixed, the application will soft disable the VSTO Add-in again. Read more about that in the How to: Re-enable a VSTO Add-in that has been disabled article.
Most probably the form is displayed behind the Outlook window. To show a form on top of the Outlook window you need to specify the parent window handle. In .net based applications or add-ins you typically use Windows forms classes to show a window. The Show and ShowDialog methods of the System.Windows.Forms.Form class accept an instance of the IWin32Window interface which stands for the parent window handle. See How to set the Window.Owner to Outlook window for more information.
Finally I found the solution, for the creation of one ticket, I'm using the system date with a specific function. But, the user who have the problem change the default setting in the Windows configuration. So the form could not be displayed due to an unmanaged exception (English date when the software expect French date).

Excel custom Add-In not loading when instance of Excel is opened by another application

I have created a custom add-in for Excel and for the most this work fine without any issues.
However, we have a 3rd party application where we can select the option to "Open In Excel". This then loads a new instance of Microsoft Excel with a load of data populated from the application, but does not load the custom add-in.
If I go in to the add-ins option, I can see that Excel still seems to think that the add-in is enabled but I can see that it is not because the macros are not imported to workbook.
I can disable and then re-enable the add-in and it will work just fine. I can also open an Excel document or a new instance manually and it will work as expected. It only ever seems to be an issue when the instance of Excel is opened from this 3rd party application.
I assume that this is because the add-in is bound to my account and the process is being started by another account even though task manager sees it as being a process ran by myself.
If anyone has any ideas as to why this is happening or how to resolve it, I would be very grateful to hear.

Dispose unmanaged resources created in Windows Form

When an object is created in the .Designer.vb file from the Windows Form Designer, is a Dispose() call generated automatically for each object or must this be done manually?
Specifically, I have an object that uses unmanaged resources (by calling ShowDialog(), requiring a call to Dispose()) that is created in the Windows Form Designer. Do I still need to call Dispose() on that object?
Note: It is advised not to call Dispose() more than once on the same object.
While I dont know the answer, let me tell you how you can get the answer and learn a neat trick for designing components for winforms (might work for others but haven't tried).
Assuming you have a project that already references your component, create a new project and set the "Start External Program" to "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" (change this based on your version of visual studio, this is from 2005)
Run this project, which will then run another instance of VS. You have now opened VS in debug mode. Now open your project you are using to build/test your component (from the second instance of VS), set a break-point and test it. You should be able to see it hit your break-point in the dispose code.
This is great for testing VS Add-ins and designer components.
This was one of those questions where the answer is "because that is the way it works", but then you realize you don't actually know how it is implemented. So I spent a few moments to dig up the details.
Anything that is a Control (button, textbox, whatever) that is added to the Controls collection is disposed for you automatically. This implementation is inherited all the way back from the Control class itself.
Anything that is a non-graphical Component (like a Timer for example) that is added to the auto-generated components object in the MyForm.Designer.vb file is also disposed for you. In this case, components object, while implementing the System.ComponentModel.IContainer interface, will be an instance of System.ComponentModel.Container that handles the actual Dispose.

How to set Focus and Modal way on a Winform/WPF Application hosted in VSTO Excel 2003 Add-in?

I have 2 questions :
1) In my VSTO Add-in, I created a button. When clicked, it starts a STA thread, launching a WPF Window (which is in fact my real application).
The application is treating Excel Data, sending them to Web services, etc etc.
At a particularly moment, I call :
System.Diagnostics.Process.Start(filePath);
the path is like "C:\file.xls". Indeed, it opens an Excel file.
The problem is that the focus is beeing made on this file instead of remaining the focus on my WPF window.
I tried to set the focus to the Current process, but since the new file opened and my WPF Window are hosted in the same Excel process, it didn't solve the problem at all...
Any idea ?
2) As you can see, as my WPF application is launched in a thread, even using a modal dialog, I can still modify the excel file in background... which is not what I want at all...
How to fix this, blocking the excel file in background ? Is it possible to do this using the Workbook COM object that I can control ?
Ok I solved my problem not using a thread.
I launch my application directly in the VSTA_Main thread (the Add-in thread), causing a freeze on my button...
Since it's not another thread, my entire process in blocking.
For the second question, I launched another Excel process like that :
ProcessStartInfo info = new ProcessStartInfo("Excel.exe",filePath);
Process.Start(info);
I still have a little bug with the generation of the Excel file, but still solved my principal problem.

Deploy Outlook UserForm

I made a userform to give out to colleagues.
The installation procedure goes approximately like this:
allow unsigned macros
open VB Editor
add 2 references by manually navigating to the .ocx / .tlb files (needed for Treeview control)
import form
create a new module
copy a procedure into that module (hook for button, contains essentially MyForm.Show)
run another proc to create toolbar button
save, restart
My plan was to make an install script; but I found Outlook's VBProject is sealed tight against any automated access.
How can I make that installation procedure simpler?
As microsoft wrote here:
https://support.microsoft.com/en-us/help/290779/managing-and-distributing-outlook-visual-basic-for-vba
If you are developing a solution that you intend to distribute to more than a few people, you should convert your VBA code into an Outlook COM or VSTO add-in or an Office add-in for Outlook.
Outlook macros are not made to be deployed so you will always have troubles deploying them to users as they will need to make too much actions as you described.
To avoid that, I recommend you to look at VSTO add-ins and ClickOnce. Here are the links:
VSTO
https://learn.microsoft.com/en-us/visualstudio/vsto/getting-started-programming-vsto-add-ins?view=vs-2019
ClickOnce deployment
https://learn.microsoft.com/en-us/visualstudio/vsto/deploying-an-office-solution-by-using-clickonce?view=vs-2019