Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

call a method from my programm/exe from commandline

Posted on 2010-11-22
12
Medium Priority
?
479 Views
Last Modified: 2013-12-17
Hi experts

I have a small c# application (.NET 3.5) which gets distributed as clickonce as an exe and is used for tasks, the users have to complete (similiar to outlook tasks)
this application then sends emails to various users. the emails contain tasks which need to be done.
What I need is a link in the emails which, upon clicking, opens the correct task in my application.
So I need to be able to call a method from my application from an external point.

I have no idea how I can do that.
Hope you can help
0
Comment
Question by:Arikael
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 5

Assisted Solution

by:buraksarica
buraksarica earned 240 total points
ID: 34188214
You can register your own protocol using Registry. Here is how to do it: http://msdn.microsoft.com/en-us/library/aa767914%28VS.85%29.aspx

with this, you can make applications open your application with given argument.

But if you want your application, not to open new instance and, call a method on the already-opened instance; then you need to make your application single-instance compatible, and send the arguments to the already-opened instance.
0
 
LVL 40

Assisted Solution

by:Kyle Abrahams
Kyle Abrahams earned 240 total points
ID: 34188219
research command line arguments.   Pass those into your program as part of the call.  
In your main, parse out the arguments (switch/select command), calling the appropriate function as needed.
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 34188241
You can register a custom URL handler in the registry, following the directions here: http://msdn.microsoft.com/en-us/library/aa767914(VS.85).aspx

Since this is a ClickOnce application you'd probably want a method in your program to do/check that each time it runs (since ClickOnce applications may have a tendancy to move around) - you could use System.Reflection.Assembly.GetExecutingAssembly().Location to determine the path to register, and register - for example - the URL myTasks.

Then you could put a URL in the email along the lines of myTasks:theTaskId
0
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
LVL 3

Author Comment

by:Arikael
ID: 34188416
Thanks for your comments
the URL-Handler thing looks very interesting, thanks for that too?

I was a bit puzzled because the main of a winForm-App doesn't take any parameters/arguments.
I assume Environment.GetCommandLineArgs(); is the way to go?
0
 
LVL 3

Author Comment

by:Arikael
ID: 34188426
oh, and perhaps storing the an instance of the application-class in a static variable of the program-class?
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 34188441
Environment.GetCommandLineArgs() will work fine (you can also change the Main() method of a Windows Forms application to accept parameters and/or return a value).
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 34188473
oh, and perhaps storing the an instance of the application-class in a static variable of the program-class?

What application class?  You mean the Application class?  All you should need to do is reference System.Windows.Forms for that class to be available.
0
 
LVL 3

Author Comment

by:Arikael
ID: 34188531
Hi

I explained it a bit weird. I meant the winform-class (the main form) which gets called via application.run(new Form())

there should only be one instance of my application running, so I thought storing my mainform in a static variable would be a way to prevent that.
if the variable is not not null, I can just get the static variable and use it.
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 34188665
That won't work quite the way you think it does.  You'll need to implement something like using a Mutext to ensure only one instance of your application is running.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			bool grantedOwnerShip;
			Mutex singleInstanceMutex = new Mutex(true, "MyAppSingleInstanceMutex", out grantedOwnerShip);
			if (!grantedOwnerShip)
			{
				MessageBox.Show("Another instance of this application is already running.");
				Environment.Exit(1);
			}

			Application.Run(new Form1());

			GC.KeepAlive(singleInstanceMutex);
		}
	}
}

Open in new window

0
 
LVL 3

Author Comment

by:Arikael
ID: 34188707
Thanks, that's what I found out after testing the  static-approach :)
http://www.sanity-free.com/143/csharp_dotnet_single_instance_application.html
this would be a way to notify my application and show the task to the user (it's the same as your suggestion with the addition of the ability to notify my app).

Basically this means that this message gets broadcasted to every window, right?
is this the best way to do it?
0
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 1520 total points
ID: 34188916
Broadcasted to every window: yes, but it's done by registering a custom Windows message so it will be meaningless to applications other than yours.

Best way: 6 of one, half dozen of the other.  I've done something similar by using a NativeWindow whose sole purpose is to listen for messages, and directing a pre-existing Windows message (WM_APP, which is reserved for application-defined use) to that Window.  I did this for a specific reason - namely that my application spends most of it's time as an icon in the system tray, and thus didn't have a form open whose WndProc I could override. Using the NativeWindow class let's me always have an "invisible" form open all the time in order to receive Windows messages.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

static class Program
{
	public const string MessageWindowCaption = "MessageListenerWindowCaption"; // A GUID string would be good here

	[STAThread]
	static void Main()
	{
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);

		bool grantedOwnerShip;
		Mutex singleInstanceMutex = new Mutex(true, "MyAppSingleInstanceMutex", out grantedOwnerShip);
		if (!grantedOwnerShip)
		{
			IntPtr hWnd = WinAPI.FindWindow(null, Program.MessageWindowCaption);
			if (hWnd != IntPtr.Zero)
				WinAPI.PostMessage(hWnd, WinAPI.WM_APP, IntPtr.Zero, IntPtr.Zero);
			return;
		}

		Application.Run(new Form1());

		GC.KeepAlive(singleInstanceMutex);
	}
}

public class Form1 : Form
{
	MessageListener _messageListener;
	public Form1()
	{
		_messageListener = new MessageListener(Program.MessageWindowCaption);
		_messageListener.MessageReceived += new EventHandler(_messageListener_MessageReceived);
	}

	void _messageListener_MessageReceived(object sender, EventArgs e)
	{
		MessageBox.Show("A second instance was attemped.");
	}
}

public class MessageListener : NativeWindow
{
	public event EventHandler MessageReceived;
	public MessageListener(string WindowCaption)
	{
		CreateParams cp = new CreateParams();
		cp.Parent = WinAPI.HWND_MESSAGE;
		cp.Caption = WindowCaption;
		CreateHandle(cp);
	}
	protected override void WndProc(ref Message m)
	{
		if (m.Msg == WinAPI.WM_APP)
			OnMessageReceived(new EventArgs());
		base.WndProc(ref m);
	}
	protected virtual void OnMessageReceived(EventArgs e)
	{
		if (MessageReceived != null)
			MessageReceived(this, e);
	}
}
public static class WinAPI
{
	[DllImport("user32.dll", SetLastError = true)]
	public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
	[DllImport("user32.dll", SetLastError = true)]
	public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

	public static readonly IntPtr HWND_MESSAGE = new IntPtr(-3);
	public const int WM_APP = 0x8000;
}

Open in new window

0
 
LVL 3

Author Comment

by:Arikael
ID: 34189019
Thanks for your help, I really appreciate it :-)

I'll have a look at your code
0

Featured Post

Interactive Way of Training for the AWS CSA Exam

An interactive way of learning that will help you visualize core concepts so that you can be more effective when taking your AWS certification exam.  Built for students by a student to help them understand the concepts that they are being taught.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question