check for existence of office.interop assemblies - c#

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

Related

C#: Create custom msi file

I need to create a custom installer to deploy a specific program. But there are a few checks and balances that needs take place during intallation, and even though I have an Advanced Installer license, it just struggles to do everything I need.
I'm looking for a way to create my own msi file using c#. Running the msi file it will then start a win forms wizard, which in turn will do a number of items, including copying files to the host PC.
I'm not sure how I can "include" my set of files into a single msi file. How to you "copy" files into an msi and how can you read again from it?
I can't even give a proper sample code of what I've tried as I don't know where to start.
This just feels like it should be a duplicate question, but I can't find it.
I work at Advanced Installer, since you said you already have a license let's help you get a return of investment on that ;)
First of all, I seriously doubt you need to reinvent the wheel and write your own code that installs/copies files on the machine. This is a basic action performed by all installer authoring tools, and even though it seems simple when you first think about it, it is not. You don't want to write code that handles rollbacks (if your install fails), reference counts (if a file is shared somehow), repair/self-healing operations (if somehow a DLL gets corrupted or missing post-install), or cover other standard Windows Installer scenarios.
Since you didn't explain with full details what you are trying to do I will give you some short example on how to do each of the steps you mentioned:
Adding files in a setup package - this is a link to a tutorial created with a free edition, but the same steps apply for Professional and Enterprise editions.
Searching files on a disk and retrieving values from them. - for this, you need to use the built-in support from Search page. There you can either simply search for a file and return its path or search for an element inside an INI or XML file and return its value inside a property.
Windows Installer properties are the equivalent of variables in your code. You can use them all over the installer project to pass/get/validate values.
Designing custom dialogs. Most professional installer authoring tools have support to build custom dialogs. The previous link is for a tutorial on how you can do that with Advanced Installer.
During the UI stages, you can include and custom C# code to perform additional validations or data retrieval operations and pass that to or from the installer using properties. if you need it.
The custom installer dialogs support is available starting with the Enterprise edition. The Professional and Free editions include the standard dialogs, but with no options to customize them.
Another way to interact with users is to design an UI experience inside your application that is visible only when the users launch the application for the first time. So, this is not a part of your installer. It will be code that you write inside your application and you can provide a first-launch experience similar to what you see when you install Office for example. If you can give me more details on what you want to do/capture in those custom dialogs, I will try to recommend you the best approach.

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

Communication between VSTO and .XLL

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.

C# - how to catch the exact moment a program is installed/uninstalled

I'm working on an application (A) that has to react and do something when a specific program (B) is installed on the system.
I've been seeing a lot of examples about listing programs already installed using the registry keys and some code to monitor status changes on programs and services using WMI.
I'm thinking I could use those combined to do what I want, say:
1. When my application (A) is started, check on the registry if my program (B) is installed or not (initial condition).
2. Then, monitor for service changes on the local machine from my application (A).
3. And every time a report of status changes comes from service "msiserver", re-check if my program (B) has been installed/uninstalled (initial condition has changed), and do something if so.
This sounds to me like I'm trying to reinvent the wheel here, and I wonder if any of you know if there's a more "natural " or "immediate" way to catch the moment/event when a specific program has been installed on the system ...or not :/
Additional considerations: The default location where the program (B) can be installed is variable, so monitoring for folders (like C:\Program Files) is not an option.
Thanks!
I'm not aware of any mechanism that would allow you to subscribed to an OnInstalled type event. You'd have to loop and detect the installation status change. Perhaps using the Microsoft.Deployment.WindowsInstaller (DTF) library to enum products and/or components. Don't use WMI... the Win32_Product class is horribly slow and querying it causes reinstalls of applications. (Don't ask... it just sucks).

Can I determine the temporary path of an open excel workbook?

I'm trying to create an excel file from ASP.NET. I assume this file is created somewhere temporary right? How can I get this location?
What are you using to create the Excel file? Since you have an ASP.NET tag I hope you are not trying to do this with Office COM Automation, it is not supported and trust me it is very very unreliable. See this link from Microsoft http://support.microsoft.com/kb/257757
Key message from the link
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
I would suggest that you take a look at using NPOI library, it is very fast and works reliably on the server side. And you can then control where the file is generated.
If you are using a temp path or a temp file you should not care about where it is. If you need to care you should use a concrete path with a concrete file. You can also use a MemoryStream to do this all without HardDisk.
EDIT:
Additional to the comment I recommend you to use Open XML to create a Excel Sheet. If this is an option let me know than will I post more on that.
I must say I didn't know this article from Chris Taylors post and if I had found this one last year it had saved me a lot of time. But what I must say at this point; it is possible to get a serverside solution running which uses interop and I need it last year. But it was a pain till it work and if anyone want to give it a try here are some advices:
you should not use interop directly
from a ASP apllication
you can't use impersonation (it may
fail unexpected)
you will need a service which runs as
System
you need a executable that runs the
interop
you have to manage the the execution
through the service (and I mean
manage, not just starting)
And again; I don't recommend to do this. Use any other solution if you. (MS Supports automation services with SharePoint2010)

Categories

Resources