Laden...

unter Compact Framework mehrere Programminstanzen verhindern?

Erstellt von dimuwe vor 14 Jahren Letzter Beitrag vor 13 Jahren 5.791 Views
D
dimuwe Themenstarter:in
168 Beiträge seit 2005
vor 14 Jahren
unter Compact Framework mehrere Programminstanzen verhindern?

Visual Studio 2008, CF2

Hallo,
ich habe hier viele Ansätze und Lösungen mit System.Threading.Mutex gelesen, die ein mehrfaches Starten der Applikation verhindern.
Leider gibt es diese Möglichkeit unter CF2 nicht.
In der OpenNetCF Klasse gibt es die Applikation2.Run Methode:


public static void Run(
	Form mainForm,
	bool runAsSingletonApp,
	bool displayMainForm
)

Nun habe ich es mit


Applikation2.Run(new MainForm(),true,true) 

versucht, aber da bekomme ich auch nicht den gewünschten Erfolg.
Gibt es da vielleicht eine bessere und funktionierende Lösung?

Besten Dank
dimuwe

1.130 Beiträge seit 2007
vor 14 Jahren
try
{
//eine leere datei erstellen und diese für die gesamte programmlaufzeit sperren:
GcHandle.Alloc(new Filestream("temp.tmp",openORCreate,Access.Read,Share.None)); // Share.None ist wichtig!
}
catch()
{
//kein lesezugriff möglich -> datei muss von anderer instanz verwendet werden!
}

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

D
dimuwe Themenstarter:in
168 Beiträge seit 2005
vor 14 Jahren

Hallo Floste,
danke für deine Antwort.
Mit einer Datei habe ich im Moment laufen, was mir aber so unsicher erscheint.


static void Main()
        {
            //Lets check if another instance of the application is already running.
            string AppDirectory = System.IO.Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().GetModules()[0].FullyQualifiedName);
            System.IO.FileInfo fiFile = null;
            foreach (string s in System.IO.Directory.GetFiles(AppDirectory))
            {
                fiFile = new System.IO.FileInfo(s);
                if (fiFile.Extension == ".proc")
                {
                    try
                    {
                        if ((System.Diagnostics.Process.GetProcessById (Convert.ToInt32 (fiFile.Name.Replace (fiFile.Extension, "")))).Responding)
                        {
                            //if application already runs in another process kill this one
                            System.Threading.ThreadPool.QueueUserWorkItem (ShowMessage);
                            System.Threading.Thread.Sleep(3000);
                            System.Diagnostics.Process.GetCurrentProcess().Kill();
                        }//end if
                    }//end try
                    catch (ArgumentException e)
                    {
                        System.IO.File.Delete(s); //löschen wenn Prozess nicht mehr aktiv
                        string BlossSo = e.Message;
                    }//end catch
                }//end if
            }//end foreach

            //Lets create a flagfile with the processID as name. so we define that the application is already running one time.
            string FileName = System.IO.Path.Combine (AppDirectory, System.Diagnostics.Process.GetCurrentProcess().Id.ToString() + ".proc");
            using (System.IO.File.Create(FileName)) { }//end using

            //Now lets start the application
            try
            {
                Application2.Run(new frmMain());
            }//end try
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }//end catch
            finally
            {
                // We delete the flag file after application exits
                if (System.IO.File.Exists(FileName))
                    System.IO.File.Delete(FileName);
            }//end finally
        }

aus diesem Grund dachte ich, dass es mit dem OpenNet oder einer ganz anderen Lösung geht. Vielleicht kann man ja diese noch verbessern?
Gruß
dimuwe

328 Beiträge seit 2006
vor 14 Jahren

Mutex ist schon das richtige Stichwort: http://www.pda-dev.de/topic.asp?TOPIC_ID=812&SearchTerms=mutex

Robert Wachtel

http://blog.robertsoft.de

S
58 Beiträge seit 2007
vor 14 Jahren

Folgende Klasse...


namespace OneOfAnAppHelp
{
    class AppExecutionManager : IDisposable
    {
        private bool _isFirstInstance;
        private IntPtr _eventHandle = IntPtr.Zero;

        #region Imports

        [DllImport("Coredll.dll", SetLastError = true)]
        static extern IntPtr CreateEvent(IntPtr alwaysZero, bool manualReset, bool initialState, string name);
        [DllImport("Coredll.dll", SetLastError = true)]
        static extern int CloseHandle(IntPtr handle);

        #endregion

        public AppExecutionManager(string appName)
        {
            _eventHandle = CreateEvent(IntPtr.Zero, true, false, appName + "Event");
            _isFirstInstance = Marshal.GetLastWin32Error() == 0;
        }
        public bool IsFirstInstance
        {
            get { return _isFirstInstance; }
        }
        public void Dispose()
        {
            if (_eventHandle != IntPtr.Zero)
                CloseHandle(_eventHandle);
        }
   }

aufgerufen mit



 static void Main()
        {
            using (AppExecutionManager execMgr = new AppExecutionManager("MeinAppName"))
            {
                if (execMgr.IsFirstInstance)
                {
                       Application.Run(new MainForm());
                }
            }
        }

funktioniert ganz fanatastisch bei mir

Der Code ist nicht von mir sondern aus dem Beispiel names AppOneCopy_CS
LINK

D
dimuwe Themenstarter:in
168 Beiträge seit 2005
vor 13 Jahren

Hallo soma,
das funktioniert wirklich gut und das ohne so eine lästige Datei.

ein Problem wäre noch, dass es sein kann das sich das gestartete Programm hinter ein anderes Fenster legt. Wie bekomme ich das wieder in den Vordergrund?

Besten Dank
dimuwe