Open Outlook on user machine

  • Thread starter Thread starter andyoye
  • Start date Start date
A

andyoye

How can I launch Outlook on users machines when they click a button on a web
form (InfoPath)?

Thanks
 
You can't.

Only client-side code can ask the client to do something. Now, you can
certainly have client code that "asks" the browser to open its default mail
client, and that *might* be Outlook, but again, it might not be.

And, for security reasons, JavaScript (the client code we're talking about)
has no abilities when it comes to the OS.
 
I found following from
http://forums.devx.com/showthread.php?t=152716&highlight=outlook

looks like I am missing some namespace/referneces as "Outlook.Application"
could not be found.


Outlook.Application objOutlk = new Outlook.Application();
//Outlook
const int olMailItem = 0;
object objMail = new object();
objMail = objOutlk.CreateItem(olMailItem);
//Email item
objMail.To = emaila.Text;
objMail.cc = "";
//Enter an address here To include a carbon copy; bcc is For blind carbon
copy's
//Set up Subject Line
objMail.subject = "Quality Assurance Letter";
//To add an attachment, use:
//objMail.attachments.add("C:\MyAttachmentFile.txt")
string msg;
msg = "body test msg";
objMail.body = msg;
//Use this To display before sending, otherwise call objMail.Send to send
without reviewing
objMail.display();
//Use this To display before sending, otherwise call objMail.Send to send
without reviewing
//Clean up
objMail = null;
 
How can I launch Outlook on users machines when they click a button on a web
form (InfoPath)?

Thanks

I do not know why do you want to open outlook, however from
application programming side, the normal requirement is to mail
something to someone... In which case System.Web.Mail will help.

- Cnu
 
Add, from Office (Setup/Add/Repair) ".Net Programmability Support" (not as
load on request, but unconditionally).

Add the reference to Office Interop to your project and the line

using Outlook=Microsoft.Office.Interop.Outlook;

(note that this alias may help to remove ambiguity about Application and
Outlook.Application)

and, to clean up, the code is missing a lot. Try adding:

objOutlk.Quit();
objOutlk= null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();


More details in"Microsoft .Net Development For Microsoft Office", Andrew
Whitechapel, Microsoft Press.


Vanderghast, Access MVP
 
I do want to open outlook, thats the MAIN objective here.

I ran below code:

Outlook.Application outlookApp = new Outlook.Application();

Outlook.MailItem message =

(Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);

message.Subject = "Hello World";

message.Recipients.Add([email protected]);

message.Body = "Hello. This is a test.";

I get below error when i try to run it.

System.Security.SecurityException
That assembly does not allow partially trusted callers.
at
System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly
asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh,
SecurityAction action, Object demand, IPermission permThatFailed)
 
You're missing the point. The code you show below will only work if it is
*running* on a machine with Outlook installed. Since you said "web form",
then this could will be running on a web server and there are two issues
with that:

1. Most web servers don't have Outlook installed on them, nor would you want
to as it poses a security risk.
2. Even if the server had Outlook (or the Outlook Primary InterOp Assembly -
PIA), this code runs on the server and won't do anything for the client.

-Scott
 
Michael,

There are a couple of things wrong with this:

1. The OP asked about opening Outlook on the client but from Web Form code,
which can't be done.
2. Your clean up code is not correct.
a. When calling a COM object via COM InterOp, you must call the
Marshall class's ReleaseComObject method, which tells the CLR to release it
connection to the underlying COM object. Since COM objects are freed from
memory when their reference count goes to zero, this step is critical
otherwise the object will persist in memory even though the .NET program
that called it no longer has any reference to it.
b. You really should not ever need to call GC anything except for under
very special circumstances. The GC runs in a separate thread from your .NET
application and the moment you call GC from your application, you force it
to operate in the same thread as your main application. This can actually
result in your application's performance degrading. The bottom line is that
the GC works quite well all on its own and you really shouldn't interfere
with its normal operations because you will most likely not improve matters.

The correct way to "clean up" a COM object from .NET is this:

objOutlook.Quit();
System.Marshall.ReleaseComObjct(objOutlook);
objOutlook = null;

-Scott
 
No.

Read the whole thread though. I've got to believe that understanding
"mailto:..." is what you need.

The person who posted the code wrote: "this should spawn on the client
machine not the web server. but then again im using an all in one so ....".

This means they were testing from the server itself. The code works fine
in a windows application. The permission errors you refered to in another
email likely are that the ASP.Net account doesn't have permission to run
outlook. Don't give it permision though...
 
I'm trying to tell you that you CAN'T try to have a web page open Outlook on
the client. So, instead your code is attempting to open a copy of Outlook
that is on the server (if you are developing on a locally running web
server, then it is attempting to open Outlook on your machine. For security
reasons (which you are getting an exception describing), this is not
allowed.

Your code would work if you were running it in a Windows Forms application.

If you really need to have email sent from the web server, don't try to open
Outlook (which not everyone has anyway), but instead use the classes in
System.Web.Mail, which requires you provide it access to an SMTP server.
You create an instance of an email, configure it and send it - - no Outlook.

-Scott
 
No, that's what I've been trying to tell you. See my newest post in the
thread for how to send an email from the server.
 
Ok for point one, but about point 2, Andrew Whitechapel mentions that
ReleaseComObject is scoped to the AppDomain and using it, you risk causing
damage to other applications in the same AppDomain since the RCW is no
longer usable by any of the managed clients in the AppDomain. Furthermore,
you should loop until it returns 0, since sometimes, it may not return 0.
That is why he proposes the sequence I reproduced and conclude that "the
best practice guideline is to not use ReleaseComObject" (page 45, "Best
Practices")


Vanderghast, Access MVP
 
It seems to me that this relates to writing Office add-in's via VSTO, which
is not the situation here.

When an Office applicatoin (such as Outlook) has an add-in written in .NET.
It runs within the context of the hosted CLR, so an AppDomain is created for
the add-in to run in.. When the add-in has completed its work, the
AppDomain within the hosted CLR ends, and thus the need to do any releasing
of COM objects (or GC cleanup for that matter), is moot.

The OP is not talking about this situation. AFAIK and based on everything
that I've read since 2002, is that when utilizing a COM object within the
context of a managed application (.NET Windows or ASP .NET), you MUST call
ReleaseCOMObject. This is because the situation is reversed. The RCW
exists in the SAME AppDomain as the main application, so just finishing the
work with the COM object won't mean the end of the AppDomain (because your
..NET application will still be running).

Think about this for a moment (or actually build a simple RCW project and
see for yourself).

1. The .NET code creates an instance of a COM object. This causes 3 items
to go into memory.
a. A variable on the managed stack.
b. A RCW instance on the managed heap (pointed to by the variable
mentioned above).
c. The COM object is instantiated and is in memory on the unmanaged
heap.

2. When your .NET application calls the .Quit() method of the COM object,
the program's UI may close, but the actual process remains in memory. Try
this yourself. You'll see that just calling .Quit() doesn't kill the
process (use the Task Manager to verify that the COM object's process is
still running).

3. If you call Marshall.ReleaseComObject(obj), you instruct the CLR to
release its (for lack of a better term) reference to the COM object on the
unmanaged heap, thus reducing its reference count to zero. In the COM
world, that is when the object is removed from memory.

4. Now that the underlying COM object has been successfully unloaded, we
still have our variable on the managed stack and our RCW on the managed
heap. At this point, it's .NET memory management as usual. You can set
your variable to null (Nothing in VB) if you like, but for a local variable,
that may not accomplish much, sice the variable will fall off the stack at
the end of the procedure anyway. Still though, it's not a bad practice to
do it.

5. Now we're just left with a managed object on the managed heap with no
references to it and the GC will clean it up if and when it deems it
necessary. No need to get the GC involved.

-Scott
 
Just one correction. "mailto:" doesn't send mail. It simply asks the
client to open its default mail client and prepares an email message. It
doesn't cause the message to be sent. Furthermore, since many people use
web-based mail, rather than an email client, using mailto: can cause a
client that does not even have an email account set up on it to open. The
user would then have to set up their client with an email account before
they could hit Send.

To be sure, if you want to have your .NET program send mail, you should
either use the Systsem.Web.Mail namespace and create a message on the server
and have the server send the message via an SMTP server or you could CDO to
go against an Exchange Sever and automate the process that way - -
System.Web.Mail is MUCH simpler.

-Scott
 
Here's an interesting thread discussing this topic and making it clear that
what you describe is a VSTO thing and not applicable to general .NET
development. As a matter of fact, this thread says that even in VSTO, you
should still call ReleaseComObject beacuse older versions of Office won't
respond the same way Office 2003 and above do.

-Scott
 
andyoye said:
How can I launch Outlook on users machines when they click a button on a web
form (InfoPath)?

There is no way to open Outlook directly from the HTML of a web page,
nor from the C# "code behind" which is executed on the server running IIS.

If, however, you are programming for your own intranet, or can guarantee
that the user is running IE and will execute code from your site with
enough privelege, you can write an embedded activeX control and call it
from javascript within your page. Because the ActiveX control will
download to the client and run there, you can do more or less anything
you could do in a normal user program.

Of course, if you write the ActiveX control in C#, you're dependent on
the correct version of .NET already being installed on the client
machine, too.
 
You cannot create ActiveX controls using .NET. An ActiveX control is a
compiled COM application that downloads to the user's client browser and
attempts to execute there. There is no such equivelent in .NET.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top