|
|
Hello everyone
I have a singleton application which works fine, sets focus to it's self if executed while still open.
Now the client wishes for this application to also be executed by a scheduled task.
Now I have the singleton working fine, and it recognises multiple instances, easy.
What I cannot get to work, is if the application is already loaded, I want to execute a public function within the main form.
This is what I have, but this fails on .Show()
private static Mutex AppMutex = new Mutex(true, "Form1");
[STAThread]
static void Main()
{
if(AppMutex.WaitOne(0, false))
{
Application.Run(new Form1());
AppMutex.ReleaseMutex();
}
else
{
Form1 _form = new Form1();
_form = (Form1) Form1.FromHandle(AppMutex.Handle);
_form.Show();
_form.Start(); // My Own Function I wish To Execute
MessageBox.Show("Already Loaded");
}
}
Thanks in advance
|
|
|
|
|
Of course the Form1 (okay, I won't comment on your choice of clas name ("Must. Control. Fist-of-death!")) you are creating is not the same instance as the one already running.
What you really want to do is simply post a custom windows message to the instance that is running, using PostMessage(), requesting it to do the operation you desire.
Matt Gerrans
|
|
|
|
|
Thanks Matt
Do you have an example or link to an example on how to do this?
BTW, I just used Form1 in a throw together, mock up application, to try to get this going
Thank you for your help
|
|
|
|
|
Sorry about the lengthy response time, but I got ravaged by some kind of stomach virus over the last few days.
Anyway, there is a Code Project article How to send a user-defined message with SendMessage, PostMessage or PostThreadMessage[^], by Georg Bedenk that I haven't read, so I'll give you a very brief description and assume that the article contains more detailed explanations, if you are interested in reading more.
Essentially, you need to define your own message, which is an integer value that won't conflict with existing Windows messages. You'll need to be able to call PostMessage() or SendMessages() Windows APIs (there may be a .NET library call for this -- Heath?) to send that message to another instance of your app. Your app will have to watch for that message and do whatever you want when it gets it (note that you could have multiple messages, or make use of lparam and wparam to get lots of different behaviors).
Here are all the chunks of code you'll need in your main form's class (which I called FormMain below), with some comments:
const int WM_APP = 0x8000;
const int WM_DO_SOMETHING_MAN = WM_APP + 1;
[DllImport("User32.Dll")]
private static extern System.Int32 PostMessage(int hwnd, int msg, int lparam, int wparam);
private static Mutex AppMutex = new Mutex(true, "TestApp");
public FormMain()
{
InitializeComponent();
SetStyle( ControlStyles.EnableNotifyMessage, true );
}
[STAThread]
static void Main()
{
if(AppMutex.WaitOne(0, false))
{
Application.Run(new FormMain());
AppMutex.ReleaseMutex();
}
else
{
Process thisProcess = Process.GetCurrentProcess();
Process [] allProcesses = System.Diagnostics.Process.GetProcesses();
foreach( Process process in allProcesses )
{
if( process.MainModule.FileName == Application.ExecutablePath )
{
if(process.Id != thisProcess.Id)
{
int hwnd = process.MainWindowHandle.ToInt32();
PostMessage( hwnd, WM_DO_SOMETHING_MAN, 0, 0 );
break;
}
}
}
}
}
protected override void OnNotifyMessage(Message m)
{
if( m.Msg == WM_DO_SOMETHING_MAN )
DoSomethingClever();
}
About the corner case bug mentioned above, there are a number of things you could do to make it more ironclad, if that is necessary. ...Actually, come to think of it, only "the one" instance that should get the messages from the stubs (all the Johnny-come-latelies that couldn't get the mutex) should have a non-zero MainWindowHandle, so adding that check may do the trick.
Anyway, you've got the gist of it and can proceed with the fine-tuning as you like.
(By the way, I had done this in C/C++ before, but not in C# or .NET before this).
Matt Gerrans
|
|
|
|
|
Mate you are a true champion!
Works a treat
Thank you so much!, If your ever in OZ, let me know, I owe you a few beers!
|
|
|
|
|
Okay, it's a deal. I wouldn't mind tossing my bike on a plane and cycling around that continent for a few weeks some time. And of course, the best fuel for that is
Matt Gerrans
|
|
|
|
|
LOL, well I can supply the , but you'll need a bit more than a few weeks to cycle around Australia, all of Western Europe fits in to Queensland, one of our 7 states/territories
BTW: The application works a treat now
|
|
|
|
|
hi
when you right click on a file we know that property page for file
appeares . ther is "Type of file" that i need to get it from my
code for any type of file.
What should i do plz?
|
|
|
|
|
I dont know the exact solution but I guess ,
you may manipulate the needed data by Using System.IO.FileInfo library
you may use the method
Path.GetExtension(), would be a solution..
|
|
|
|
|
hi,
this may be tricky bt if it's Windows system... do you know how registry works? "Type of file" is stored in H_KEY_CLASSES ... Actually there are both extentions (say ".txt") and file classes (say "txtfile"). under ".txt" key is name of file class. In file class there are subkeys describing icon, context menu, description... There is Type of file: "Text Document" stored.
Ugly... I know.. Probably switch for extentions will be enough
if not search MSDN for Registry; File Types; etc
best regards,
David 'DNH' Nohejl
Never forget: "Stay kul and happy" (I.A.)
|
|
|
|
|
Its not ugly unless you are only going to list the items.. and you dont want to deal with windows
By the way, the first code that I wrote down, is for a given path...
But if you want to search all items in a directory and get all the types , the following code will be sufficient..
and dont forget to add using System.File
<br />
string[] files = Directory.GetFiles(workingDirectory);<br />
<br />
foreach (string s in files)<br />
{<br />
FileInfo fi = new FileInfo(s);<br />
fi.Extension
I dont know anything about the above coding sample , but I searched a little bit , and I remembered FileInfo , and the following article ("CrytoSave"-chech it out), made the message constructed Thats the reason why I love CP
|
|
|
|
|
Bahadir Cambel wrote:
ts not ugly unless you are only going to list the items.. and you dont want to deal with windows
well, MY solution is ugly (as whole registry thing) and I stand my ground (or how it is this idiom). I didn't mean your code- it's ok afer all.
Yes he may want to know only file type... in this case your code is ok (and mine is useless - and vice versa).
Bt if he wants to get longer description of file type (how it's called on targer system - e.g .bmp may be called "bitmap file" as well as "PSP Image file" if PaintShopPro program is installed - cuz it modifies registry), then my way is way to go. AFIAK FileInfo doesn't contain this information. I did quick search at MSDN its possible I overlooked it bt again, I don't think so. (One reason - it may be Windows specific feature).
Bahadir Cambel wrote:
Thats the reason why I love CP
yeah, I love CP as well!
David
Never forget: "Stay kul and happy" (I.A.)
|
|
|
|
|
I know You used the "ugly" word for your registry thing..not my simple code
But as you said we didnt know what he/she wants..So lets consider the simple solution , if unsuffient , hurrahhh to the windows registriess ( Oh nooo!! )
|
|
|
|
|
I read my client configuration from a config file, and it opened my channel sucefully. But, I still have to pass my url string at Activator.GetObject... well, I want to call my activator.getobject without to pass the url or get the url dinamically with channelservices.
PS: My object isn't know at client side, so I can't do just a MyObj o = new MyObj(); I need to do something like this
MyObj o = (IObj)Activator.GetObject(typeof(IObj),"tcp://localhost:9999/MyObj"); but without this url. I want to use the channel that is already opened by RemotingConfiguration.Configure(file).
Thanks so much
Wender Oliveira
.NET Programmer
|
|
|
|
|
Activator.GetObject() has no knowledege of any type registration at all - type registration exists purely for the benefit of the Activator.CreateInstance() and new activation models.
I'm fairly certain that Activator.CreateInstance() requires the type that is being remoted to be available locally as well (new definitely does).
In conclusion, I think you'll have to stick with Activator.GetObject() (and hence passing the URI a lot), unless the type information is available on the client (maybe you could implement a stub class). I'd like to be proved wrong, however! Perhaps there's an advanced use of Activator.CreateInstance() that I've missed.
This space for rent!
My Blog
|
|
|
|
|
hi
i have a file and want to send it to webservice so
i have to create a byte[ ] and populate it with file.
what should i do for File to byte[ ] ?
thanks.
|
|
|
|
|
just change your max file size and filepath...
const int MaxSize = 1000;
string FilePath = @"C:\test.txt";
byte[] b = new byte[MaxSize];
FileStream f = new FileStream(FilePath,FileMode.Open);
f.Read(b,0,(int)f.Length);
Wender Oliveira
.NET Programmer
|
|
|
|
|
Wender Oliveira wrote:
just change your max file size and filepath...
const int MaxSize = 1000;
string FilePath = @"C:\test.txt";
byte[] b = new byte[MaxSize];
FileStream f = new FileStream(FilePath,FileMode.Open);
f.Read(b,0,(int)f.Length);
No. I've seen it many times and it is just wrong. You end up with an array with then length 1000. How does that reflect the content of the array? It doesn't. The object processing the array has to analyze the data in order to find out the length of the actual user data (sometimes that might even be impossible). And what if MaxSize is much larger? Just read the entire file as originally asked for and if you want to introduce a limit then use something like this (and make sure the receiving object is aware of the fact that the data might be truncated):
byte[] MyArray = null;
const int MaxSize = 1000;
string FilePath = @"C:\test.txt";
FileInfo MyFile = new FileInfo(FilePath);
if (MyFile.Length > MaxSize)
MyArray = new byte[MaxSize];
else
MyArray = new byte[MyFile.Length];
Best regards
Dennis
|
|
|
|
|
anybody know how to build patch to fix program without re-compile program.
|
|
|
|
|
I want to in C# be able:
1. create a text file
2. save it
3. Make a change to the text file
4. Save only the changes, which can be merged back into the original file.
This is basically a poor mans version control system in C#.
I have found examples of how to compare two files byte by byte. I am hoping someone has seen an efficient way to save the changes before I start rolling my own.
Thanks,
Darren
|
|
|
|
|
|
There are a lot of interfaces in .Net ,
how and when should we use these interfaces ?
IContainer , IDisposable , IComponent are some of them that I've seen around..
Could you explain me ?
And give some advice ..
Thanks a lot..
|
|
|
|
|
Interfaces is a method to provide polymorphism without having to implement multiple inheritance.
An interface is a description of a subset of properties and methods of an object. If an object is declared to implement an interface, then it must provide all the properties and methods of that interface.
A good example of the usefullness of interfaces is IDisposable. Let's say that you got a list of objects. The objects are all of different types, but you know that some of those objects needs to release their internal resources when you're done using them. Here is how you could do it:
foreach (IDisposable disposableObject in listOfVariousClassInstances)
{
disposableObject.Dispose();
}
In the example above, you don't care if the object at hand is a Brush, BinaryWriter or a Cursor, you simply narrows the object to an IDisposable and invokes the one and only method available: Dispose().
When to create an interface: If you expect that your class hierarchy contains classes that share common methods and properties, you will of course use inheritance:
public class Base
{
protected int i;
public int I
{
get:
{
return i;
}
}
}
public class A: Base
{
protected int j;
public int J
{
get:
{
return j;
}
}
}
public class B: Base
{
protected int k;
public int K
{
get:
{
return k;
}
}
}
But suppose that you want class B to be a list of objects too. All that functionality could be easily provided by extending class System.Collections.ArrayList, but then you can't inherit from class Base. You know that other classes in your hierarchy will refer to B.I, so you now have the choice to either reinvent the functionality of ArrayList, or create a common interface for your classes.
In this case, it seems that your classes aren't that related, which in itself begs for an interface solution, but it's quite clear, that it should be easier to copy/paste the I property to all of your classes, than to reinvent ArrayList:
public interface IBase
{
int I
{
get;
}
}
public class A: IBase
{
protected int j;
protected int i;
public int I
{
get:
{
return i;
}
}
public int J
{
get:
{
return j;
}
}
}
public class B: ArrayList, IBase
{
protected int k;
protected int i;
public int I
{
get:
{
return i;
}
}
public int K
{
get:
{
return k;
}
}
}
"After all it's just text at the end of the day. - Colin Davies
"For example, when a VB programmer comes to my house, they may say 'does your pool need cleaning, sir ?' " - Christian Graus
|
|
|
|
|
Thanks a lot for the examples and the explanations.
|
|
|
|
|