Communication between VSTO and .XLL - c#

In Visual Studio, I have a solution. In that solution I have 2 projects. One is a VSTO so that we can make a plugin for Excel. The other project is for creating a .xll file so that we can have Custom Functions.
The VSTO helps us create a login system on excel so that they can do certain things.
However, since we only want our users to be able to use our custom functions they have to log in. I think that these 2 projects can't communicate directly so the .xll addin wouldn't know if a user is logged in or not.
Is there anyway for these 2 projects to communicate? Perhaps via a middle-man like a class with static variables?
EDIT:
More information:
Both projects are written in C# code. I was able to do that for the .xll file by using ExcelDNA.
So if there's any way that I can create maybe a C# class that can coordinate or share data between the two projects that would be really great. Since login data isn't the only thing that we want to share.
I'm hoping in the class there would be a static boolean variable holding whether the user is logged in. So the VSTO could set the boolean value and the .xll could get it.

You could add a hidden function [ExcelFunction(IsHidden=true)] to the .xll, which you can call from the VSTO add-in with Application.Run.

I would use a licensing system that let the user validate a licence key. This process can takes place within the VSTO. Then I would use two checks :
if in the VSTO the licence key is validated then load the xll, otherwise do not load it.
within the xll, by using relative path, I would locate and check a second time the licence key (to prevent that the user loads directly the xll).
It just requires to be able to check the licence key in C# (VSTO) and C (Xll), ie to have a validation key algorithm implemented in both languages.

Related

Extend outlook rules Actions using vsto

I Want to create custom code that will run when the user decides based on outlook's rules.
so far i checked a few possibilities:
1)Create a custom Action that would be added to the rules actions options - that is not possible according to MS - https://social.msdn.microsoft.com/Forums/vstudio/en-US/1bae2bbc-0ab4-419a-b0d6-7a02195348ce/outlook-custom-action-in-rules-wizard?forum=vsto
2)Run Script based on a rule - built in ability, however i encountered a few issues:
it is not possible to share the script
the macro's have to be enabled each time (disabled again when you restart)
I want to use the C# VSTO add-in in order to overcome those problems:
Is there a way to implant the script and make sure the macro is enabled using a VSTO add-in?
this way users will be able to install the add-in and then chose the script as an action to every rule they create based on the default outlook rules.
You don't need a rule if your code is in a VSTO addin. You can use Items.ItemAdd event on the Inbox folder or Application.NewMailEx event to so anything your please with the newly arrived message.

Force an Excel file to be associated with a VSTO addin

This is my use case:
I need to develop a excel VSTO add-in that prevents a user from accessing a excel file unless the add-in is installed. This add-in basically authenticates the current user, and if that is successful, it will grant them access to the file. Basically I need a way to protect a file that uses my own authentication (and not the built-in password protection provided by Microsoft. Why? Because I need to be able to revoke access to the file and a local password would prevent me from doing so)
I know how to write the add-in, what I don't know is, how do I force a file to be associated with that plugin? I tried using a custom property, but that is very hack-able. Basically, I would have a custom property that says: "use this add-in", but a knowledgeable user could just go in Advanced Properties and simply delete it.
My suggestion would be for you to use COM Add-ins, as they do not distribute the code to the user and can't be easily hacked. A simple Add-in, that uses .XLA or .XLAM files are simply password protected VBA projects that can be hacked.
Now, for your workbook, I suggest you encrypt and scramble all the data and use your COM Add-in to decrypt your data and use a function to prevent saving the workbook un-encrypted. You could just override the Workbook_OnSave method to encrypt on saving. Also disable copying of cell values.
For this part, I don't know if this is possible, but you would need to override user access to VBA editor, so they couldn't walk around your add-in protections and also disable the access to options menu to disable the Add-in. That can be achieved by overwriting the Excels shortcut keys and hiding the menu bar.
Again, for the last part, I don't know if it's actually possible to limit user access to VBA editor. I think it would be pretty similar as limiting access to Add-in controls by overriding ALT+F11 shortcut and just hiding the developers tab as a whole.
Well that's my two cents, good luck!

Share code between office applications

I have written two addins , 1 for excel and 1 for word. However these addins have a lot of duplicates: Database handling, file handling,array handling which I would like to update 1 place instead of two.
We do have access to sharepoint, and could get access to visual studio. The thing is that people like to use file explorer and find the correct word or excel file, then open it then press a button inside the application which then should do things with the active document.
This is why we haven't written it as a .Net application yet, because that requires that people browse for the file inside the .NET application uless I am mistaken.
Is it possible to make an Addin which works both excel and word, or a dll? AnAnother important thing is that it should be easy to roll out a new version to the user, like stored on a network drive or similar.
Yes it is possible
The Hard Way
You can create a .Net DLL and call it from VBA. In visual studio a lot of people use Unmannaged Exports by Robert Giesecke to create DLLs that don't need to be registered (that way the DLL can be shipped with your document, and as long as it can be found you can use it).
Alternatively you might be able to do it manually as shown here by Hans Passant.
The Easy Way
Once the DLL is created you can declare it in a VBA module the same way you declare any other DLL for Late Binding and then call it from your code.
OR if you're happy to create the DLL and add it as a reference (possibly less portable) you can make it COM visible and register it for COM Interop in Visual Studio; this is probably the easiest way to go because you can then use Early Binding.
This is a walk through that might help: http://www.geeksengine.com/article/create-dll.html
But if you want to store the DLL on a network drive, well it might be that you really want to look at doing it the 'hard way', in which case look here: https://stackoverflow.com/a/5934745/3451115 and here: https://msdn.microsoft.com/en-us/library/bb687915.aspx

How to start new word instance without add-ins when word is already started

I am using Word (from 2007 to 2013) to convert documents to PDFA format,
and i'm having trouble with users who have certain add-ins. When they use the system they get an assortment of COM Exceptions like RPC_E_SERVERCALL_RETRYLATER and (0x800706BA) RPC server unavailable.
If they disable the add-ins it works fine. Problem is that the add-ins are required so that simple solution is out the window. (Also I know that using word for this kind of thing is frowned upon, and we are looking into getting something better, but until the business side want's to pay, we are stuck with this)
The new plan is to start word with the /a parameter to make it start without add-ins.
I have seen another question How can I start MS Office Word from .NET without Add-ins?
Where there is a working solution for one instance of Word,
//startup without plugins
System.Diagnostics.Process.Start(
#"Winword.exe",
#"/a");
//give a time for startup
Thread.Sleep(2000);
//attach to office
Application officeApplication = (Application)Marshal.GetActiveObject("Word.Application");
My question is two fold: Is it possible to set startup parameters when you start word like this
var _word = new Word.Application();
So I don't have to use Process.start();
And if not, how do I do a late bind to a specific word instance (GetActiveObject(), always gets the oldest word instance), perhaps there is some other method?
To your first question, there's no way to pass parameters or otherwise influence how Word starts when using the new keyword. The instructions for starting the application are in the Registry, so it would involve changing how the new keyword is implemented in the Registry. And since this Registry entry also determines how Windows Explorer starts the Word.Application, changing the Registry entry would also change the way Word works for the user.
It is possible to unload add-ins after an instance of Word has started via the Application.COMAddins property. This is the equivalent of unchecking the boxes next to the Add-in entries in the COM Add-ins dialog box in the Word UI. I would test whether doing this in the UI allows your software to work properly.
If it does, you can incorporate this in your code - no need to worry about starting Word without the add-ins.
Which brings us to the second question: GetActiveObject is only able to access the single instance of Word (any Office application) registered in the ROT. By design, Office applications register only a single instance in the ROT and usually, this will be the first instance. There are a couple of KB articles on MSDN that describe this. The only work-around is to start two instances of Word in the user profile, "hiding" the first (the registered) one and presenting the second to the user.
But this can be tricky, so if it works, I'd go with the suggestion about the COMAddins collection to unload the problem Add-ins.
(I'm currently on a mobile device. Next time I'm on my main machine I'll try to remember to paste in the links to the KB articles on the ROT.)

check for existence of office.interop assemblies

I'm working on a c# project where I get input from Office documents, and right now I'm using MS Office for it. This simply means the MS Office interop components have to be present on the user's PC for this to work.
However, I might implement OpenOffice.org into it too eventually, and in that case I want my application to be automatically able to choose which program to use to process files based on what is available.
Is there any simple way to test whether certain references I made in my project are actually available on the computer that is running the program? I really don't want to release different binaries based on Office types.
What about a simple try catch block?
If the DLL is not present on the system then the most basic call will return a meaningful error. In that particular case you can load another class that will handle a different word or speadsheet processor

Categories

Resources