Torna al Thread

[DllImport("coredll")] static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, int flAllocationType, int flProtect); const int MEM_COMMITT = 0x1000; const int MEM_RESERVE = 0x2000; const int PAGE_READWRITE = 0x04; [DllImport("coredll")] static extern bool VirtualFree(IntPtr lpAddress, int dwSize, int dwFreeType); const int MEM_RELEASE = 0x8000; [DllImport("coredll")] static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, out int plNumberOfBytesRead); [DllImport("coredll")] static extern IntPtr OpenProcess(int fdwAccess, bool fInherit, int IDProcess); [DllImport("coredll")] static extern bool CloseHandle(IntPtr hObject); IntPtr memPtr = IntPtr.Zero; private void TuaForm_Load(object sender, EventArgs e) { unsafe { string tmpPath = Path.Combine(Path.GetTempPath(), "AliveTest.tmp"); //Verifica l'esistenza del file if (File.Exists(tmpPath)) { //Apre il file per leggere il percorso in memoria FileStream fStr = new FileStream(tmpPath, FileMode.Open, FileAccess.Read); //Legge i quattro byte che indicano l'id del processo byte[] idBytes = new byte[4]; fStr.Read(idBytes, 0, 4); //Legge i 4 byte che identificano l'indirizzo in memoria byte[] ptrBytes = new byte[4]; fStr.Read(ptrBytes, 0, 4); //Chiude il file fStr.Close(); //Lo stato int status; try { //Ottiene l'indirizzo in memoria memPtr = new IntPtr(BitConverter.ToInt32(ptrBytes, 0)); //Ottiene il processo dall'id IntPtr hProc = OpenProcess(0, false, BitConverter.ToInt32(idBytes, 0)); //Legge la memoria dal processo int data, read; if (hProc == IntPtr.Zero || !ReadProcessMemory(hProc, memPtr, new IntPtr(&status), 4, out read)) { //Se si sono verificati errori generea un'eccezione CloseHandle(hProc); throw new Exception(); } CloseHandle(hProc); } //Se si verificano errori di lettura della memoria //significa che il processo è terminato e il file //non è stato eliminato, quindi alloca la nuova memoria //e scrive l'indirizzo nel file catch (Exception ex) { //Indica che lo stato dovrebbe essere "non avviato" status = 0; } //Se lo stato indica che un'applicazione è in corso if (status == 1) { //Termina il processo corrente Process.GetCurrentProcess().Kill(); } //Se invece lo stato non è "applicazione in corso" //alloca la nuova memoria e scrive l'indirizzo nel file else { //Alloca la memoria memPtr = VirtualAlloc(IntPtr.Zero, 4, MEM_COMMITT | MEM_RESERVE, PAGE_READWRITE); //Scrive nella memoria che l'applicazione è in corso Marshal.WriteInt32(memPtr, 1); //Scrive l'id del processo nel file fStr = new FileStream(tmpPath, FileMode.Open, FileAccess.Write); fStr.Write(BitConverter.GetBytes(Process.GetCurrentProcess().Id), 0, 4); //Scrive il puntatore nel file fStr.Write(BitConverter.GetBytes(memPtr.ToInt32()), 0, 4); fStr.Close(); //Esce dalla funzione return; } } //Se invece il file non esiste significa che //nessun'altra istanza dell'applicazione è avviata else { //Quindi alloca la memoria, scrive lo stato e scrive //l'indirizzo dell'applicazione nel file FileStream fStr = new FileStream(tmpPath, FileMode.CreateNew, FileAccess.Write); int* i = (int*)memPtr.ToPointer(); //Alloca la memoria memPtr = VirtualAlloc(IntPtr.Zero, 4, MEM_COMMITT | MEM_RESERVE, PAGE_READWRITE); //Scrive nella memoria che l'applicazione è in corso Marshal.WriteInt32(memPtr, 1); //Scrive l'id del processo nel file fStr.Write(BitConverter.GetBytes(Process.GetCurrentProcess().Id), 0, 4); //Scrive il puntatore nel file fStr.Write(BitConverter.GetBytes(memPtr.ToInt32()), 0, 4); fStr.Close(); //Esce dalla funzione return; } } } private void Form1_Closed(object sender, EventArgs e) { //Alla chiusura del Form elimina il file temporaneo string tmpPath = Path.Combine(Path.GetTempPath(), "AliveTest.tmp"); if (File.Exists(tmpPath)) File.Delete(tmpPath); //E dealloca la memoria condivisa VirtualFree(memPtr, 0, MEM_RELEASE); }
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5