Program rejstrujący czas pracy komputera

0

W c++ jestem jeszcze początkującym programistą (do tej pory "bawiłem się" c i php). Ze względu na prośbę moich opiekunów ( :-D ) zabrałem się za pisanie programu jak w temacie, czyli program do kontroli pracowników. Założenie jest takie:

  • program zapamiętuje datę włączenia komputera (jest wrzucony do autostartu) i chodzi cały czas jako proces. W momencie wyłączania systemu do pliku time.dat ma dopisywać kolejną linijkę zawierającą:
    start = time(0) - moment uruchomienia programu
    end = time(0) - moment wyłączenia programu
    start|end|end-start
    jak na razie udało mi się wymodzić coś takiego:
#include <windows.h>
#include <iostream>
#include <fstream.h>
#include <iomanip.h>


LPSTR NazwaKlasy = "Klasa Okienka";
MSG Komunikat;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int start=0, end=0;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
     if(start==0) start=time(0);

//Pętla komunikatów
 while(GetMessage(&Komunikat, NULL, 0, 0))
 {
  TranslateMessage(&Komunikat);
  DispatchMessage(&Komunikat);
 }
 return Komunikat.wParam;
}

//OBSŁUGA ZDARZEŃ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        
        ofstream f;
        f.open("c:/time.dat");
 switch(msg)
 {
  case WM_CLOSE:
       end=time(0);
       f << start << "|" << end << "|" << end-start << endl;
       f << flush;
       f.close();
       DestroyWindow(hwnd);
  break;
  case WM_DESTROY:
       end=time(0);
       f << start << "|" << end << "|" << end-start << endl;
       f << flush;
       f.close();
       PostQuitMessage(0);
  break;
  default:
   return DefWindowProc(hwnd, msg, wParam, lParam);
   
  }
 return 0;
}

opis już jest więc czas przejść do problemu.

  1. czy podczas wyłączania systemu program wykona operacje zapisania do pliku (testowałem to, jakoś nie wychodzi... :-/ ) co należało by zmienić aby tak działał.
  2. czy w ten sposób będe dopisywał kolejne linijki do pliku czy nadpisywał ostatnią.

Bym był wdzięczny nie za "gotowca", a bardziej za linka z czymś do poczytania. Przeszukałem wmiare moich możliwości googl'a, ale do końca nie wiem czego mam szukać.

Z góry dzięki Michał.</cpp>

0
  1. czy podczas wyłączania systemu program wykona operacje zapisania do pliku (testowałem to, jakoś nie wychodzi... )

Lepiej dopisać obsługę WM_QUERYENDSESSION lub WM_ENDSESSION. (zdaje się że WM_CLOSE może tu nie zadziałać).
Komunikat jest wysyłany do programu podczas kończenia pracy systemu .
Po odebraniu tego komunikatu można zapisać do pliku czas wyłączenia i zamknąć plik .
Ostatnio napisałem taki program ( ale pod C++ Builder) do kontroli czasu marnowego
na gry , gdy nie ma mnie w domu .
Zapisuje które konto było używane i sposób zamknięcia systemu w pliku w postaci :

System_start - 2008-01-17 18:17:24 - user- Tato
System_stop_ - 2008-01-17 18:23:37 - ENDSESSION.

System_start - 2008-01-17 19:02:03 - user- Tato
System_stop_ - 2008-01-17 19:21:09 - ENDSESSION.

System_start - 2008-01-17 19:26:16 - user- Dawid
System_stop_ - 2008-01-17 19:49:27 - ENDSESSION.

System_start - 2008-01-17 20:03:08 - user- Misiek
System_stop_ - 2008-01-17 20:18:08 - END -RESET.

Ps.
Aby uchwycić sposób zamknięcia systemu [ normalne lub reset ] program musi zapisywać
co pewien okres aktualny czas i datę , nadpisując ostatnią linijkę .
Mój robi to co 1 minutę za pomocą Timera [ czyli jeśli API to obsługa WM_TIMER ].

Jeśli będziesz zapisywał wyłącznie dane do pliku w czasie uruchamiania i zamykania
programu , to reset komputera może je zafałszować lub zniszczyć strukturę pliku .
Event , będzie brakować wpisu o zamknięciu systemu .

PS.

Twój kod jest nie kompletny i program nie działa , procedura WndProc nie wykonuje się .
Musisz ją powiązać z jakimś oknem [ może być niewidoczne ] .

CALLBACK <- WndProc procedura jest wywoływana po otrzymaniu komunikatu ( cyklicznie )
przez okno i kończy działanie , a więc wsztstkie obiekty lokalne w niej utworzone znikną [ ofstream f;]
trzeba użyć obiektu statycznego lub wskaźników dostępnych na zewnątrz WndProc na obiekty tworzone np w WM_CREATE , lub obiektów tworzonych w WinMain event Globalnych .

Uwaga 1 ostatni wpis w pliku C:\timelogs.txt jest zapisem czasu bieżącej sesji z założeniem -RESET
Uwaga 2 program nie tworzy widocznego okna .

/*  timelog - dzejo - 4.02.2008 */
#include <windows.h>
#include <stdio.h>

#define ID_TIMER 1
HWND hwndMain;
HANDLE hFile  ;

char UserName[50] ;
DWORD LenUserName = sizeof(UserName) ;

char TimeBuff[24] ;
char DateBuff[24] ;
char OutBuf[120] = {0}  ;

char INFO_Session[] ={" - ENDSESSION "} ;
                                // Zakończono pracę na komputerze

char INFO_Reset[]   ={" - END_RESET  "} ;
                                // Wyłączenie - reset

char INFO_CloseApp[]={" - ENDAPPCLOSE"} ;
                                // Zamknięto aplikację managerem zadań [ Nie działa w NT ,only 98]

char INFO_SystemStart[]={"System_Start - "}; // start windows
char INFO_SystemStop[] ={"System_Stop_ - "}; // zatrzymanie

int LenOutBuf ;

LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

HANDLE OpenLogFile(LPCTSTR pFileName);

void   WriteTimeStart(HANDLE file, LPTSTR buf ,LPTSTR date,LPTSTR time, LPTSTR user);

int    WriteTimeStop(HANDLE file, LPTSTR buf ,LPTSTR date,LPTSTR time, LPTSTR status);

void   GetDateTime(void);

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR /*lpszCmdLine*/, int /*nCmdShow*/)
{

    MSG msg;
    WNDCLASS wc;

    CreateMutex(NULL, false, "2315757_ala_ma_kota");
    if(GetLastError()>0)
    {
      MessageBox(NULL,"Aplikacja jest już uruchomiona.","Uwaga",MB_OK);
      return FALSE ;
    }

    // Register the window class for the main window
    if (!hPrevInstance)
    {
        wc.style = 0;
        wc.lpfnWndProc = (WNDPROC) WndProc;
        wc.cbClsExtra = 0; 
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = NULL ;
        wc.hCursor = NULL ;
        wc.hbrBackground = NULL;
        wc.lpszMenuName =  NULL;
        wc.lpszClassName = "MainWndClass";
 
        if (!RegisterClass(&wc))
            return FALSE;
    }

    // Create the main window.

    hwndMain = CreateWindow("MainWndClass", "Timelog",
                 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                 CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,
                 (HMENU) NULL, hInstance, (LPVOID) NULL);

    // If the main window cannot be created, terminate 
    // the application.
 
    if (!hwndMain)
        return FALSE;

    // Okno nie będzie widoczne
    /* ShowWindow(hwndMain, SW_SHOW );
       UpdateWindow(hwndMain); */

    hFile = OpenLogFile("C:\\timelogs.txt");
    if(!hFile)
       return FALSE ;

    SetFilePointer(hFile,0,NULL,FILE_END); // idz na koniec pliku

    GetUserName(UserName,&LenUserName);    // pobierz nazwę uzytkownika

    GetDateTime();                   // pobierz czas i datę uruchonienia

    // Zapisz do pliku czas i date uruchomienia
WriteTimeStart(hFile,OutBuf,DateBuff,TimeBuff,UserName);
    // Zapisz do pliku czas i date zamknięcia
LenOutBuf = WriteTimeStop(hFile,OutBuf,DateBuff,TimeBuff,INFO_Reset);
    // Uruchom Timer
    SetTimer(hwndMain,ID_TIMER,30000,NULL); // 0,5 minuty

    // Start the message loop.
    while (GetMessage(&msg, (HWND) NULL, 0, 0))
    { 
        TranslateMessage(&msg);
        DispatchMessage(&msg); 
    }

    return msg.wParam;
}
//--------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{

  switch(uMsg)
  {
case WM_TIMER:

 GetDateTime();
SetFilePointer(hFile,-(LenOutBuf),NULL,FILE_END );
 WriteTimeStop(hFile,OutBuf,DateBuff,TimeBuff,INFO_Reset);
     return 0 ;

case WM_CLOSE:

     KillTimer(hwnd,ID_TIMER);
 GetDateTime();
SetFilePointer(hFile,-(LenOutBuf),NULL,FILE_END );
 WriteTimeStop(hFile,OutBuf,DateBuff,TimeBuff,INFO_CloseApp);

     CloseHandle(hFile);
     break ;

case WM_QUERYENDSESSION:           //<- lub WM_ENDSESSION

     KillTimer(hwnd,ID_TIMER);
 GetDateTime();
SetFilePointer(hFile,-(LenOutBuf),NULL,FILE_END );
 WriteTimeStop(hFile,OutBuf,DateBuff,TimeBuff,INFO_Session);

     CloseHandle(hFile);
     break ;                 //<- lub return 0 ; jeśli WM_ENDSESSION 
     
    case WM_DESTROY:
      PostQuitMessage(0); /* zakończ program */
      return 0;
    }

    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
//-----------------------------------------------------------------------------
HANDLE OpenLogFile(LPCTSTR pFileName)
{
  HANDLE pFile ;
    pFile = CreateFile(pFileName,GENERIC_WRITE,
           FILE_SHARE_READ,NULL,OPEN_ALWAYS	,
           FILE_ATTRIBUTE_NORMAL ,NULL);
    if(INVALID_HANDLE_VALUE == pFile)
    {
      MessageBox(NULL, "Error","Nie można otworzyć pliku.",MB_OK);
      return NULL;
    }
      return pFile  ;
}
//-----------------------------------------------------------------------------
void   WriteTimeStart(HANDLE file, LPTSTR Out ,LPTSTR date,LPTSTR time,LPTSTR user )
{
  DWORD len ;
  sprintf(Out,"\r\n%s %s %s %s\r\n",INFO_SystemStart,date,time,user);
  WriteFile(file,Out,lstrlen(Out),&len,NULL);
}
//-----------------------------------------------------------------------------
int WriteTimeStop(HANDLE file, LPTSTR Out ,LPTSTR date,LPTSTR time, LPTSTR status)
{
   DWORD len ;
   sprintf(Out,"%s %s %s %s\r\n",INFO_SystemStop,date,time,status);
   WriteFile(file,Out,lstrlen(Out),&len,NULL);
   return lstrlen(Out);
}
//----------------------------------------------------------------------------
void   GetDateTime(void)
{
GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,
                  NULL,"dd'-'MM'-'yyyy",DateBuff,sizeof(DateBuff));

GetTimeFormat(LOCALE_SYSTEM_DEFAULT	,TIME_FORCE24HOURFORMAT,
                  NULL,"HH':'mm':'ss ",TimeBuff,sizeof(TimeBuff));
}

A,masz - przeróbka z Buildera VCL na API .

0

siema to jest bardzo ciekawe ale ja jestem jeszcze początkujący i nie za bardzo kminie gdzie ten kod wrzucić aby program działał z góry dzięki za jakieś podpowiedzi

0

Dzięki dzejo za pomoc!
Co nieco zgapiłem kodu - ogólne założenia ale info wyszukane i doczytane na googl'u :) )

W trakcie pisania naszła mnie myśl czy jestem wstanie sprawdzić jaki program odpala użytkownik i, z którego aktualnie korzysta?

PS.
Wygląda to tak:

#include <time.h>
#include <windows.h>
#include <stdio.h>


LPSTR NazwaKlasy = "Klasa Okienka";
MSG Komunikat;
HWND hwnd;


int LenBufor;
char TextBuf[120] = {0}  ;
HANDLE hFile  ;


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/*************************************
 * HANDLE OpenFile(LPCTSTR pFileName);
 * pFileName - adres pliku do edycji
 *
 * Zwraca wskażnik do otwartego pliku
 *************************************/
HANDLE OpenFile(LPCTSTR pFileName);
/*************************************
 * int EndTime(HANDLE file, LPTSTR FileData);
 * FileData - bufor danych do pliku
 * file - wskaźnik do otwartego pliku
 *
 * Zwraca długość buforu pliku
 *************************************/
int EndTime(HANDLE file, LPTSTR FileData);
/*************************************
 * int EndTime(HANDLE file, LPTSTR FileData);
 * FileData - bufor danych do pliku
 * file - wskaźnik do otwartego pliku
 *************************************/
void StartTime(HANDLE file, LPTSTR FileData);
//------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NazwaKlasy;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

//REJESTROWANIE KLASY OKNA
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "CRITICAL ERROR", "Cannot load window", MB_ICONEXCLAMATION | MB_OK);
        return 1;
    }

//TWORZENIE OKNA
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, 
                          NazwaKlasy, 
                          "Oto okienko", 
                          WS_OVERLAPPEDWINDOW, 
                          CW_USEDEFAULT, 
                          CW_USEDEFAULT, 
                          240, 
                          120, 
                          NULL, 
                          NULL, 
                          hInstance, 
                          NULL);
    if(hwnd==NULL)
    {
        MessageBox(NULL, "CRITICAL ERROR", "Cannot load window", MB_ICONEXCLAMATION);
        return 1;
    }
    hFile=OpenFile("c:/info.dat");
    SetFilePointer(hFile,0,NULL,FILE_END); 
    StartTime(hFile, TextBuf);
    LenBufor=EndTime(hFile, TextBuf);
    SetTimer(hwnd, 1, 60000, NULL);

    //Pętla komunikatów
    while(GetMessage(&Komunikat, NULL, 0, 0))
    {
        TranslateMessage(&Komunikat);
        DispatchMessage(&Komunikat);
    }
    return Komunikat.wParam;
}



//OBSŁUGA ZDARZEŃ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
    case WM_TIMER:
        SetFilePointer(hFile,-(LenBufor),NULL,FILE_END );
        EndTime(hFile, TextBuf);
    break;
    case WM_QUERYENDSESSION:  
        KillTimer(hwnd,1);
        SetFilePointer(hFile,-(LenBufor),NULL,FILE_END );
        EndTime(hFile, TextBuf);
        CloseHandle(hFile);
    break;
    case WM_CLOSE:
        KillTimer(hwnd,1);
        SetFilePointer(hFile,-(LenBufor),NULL,FILE_END );
        EndTime(hFile, TextBuf);
        DestroyWindow(hwnd);
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
    break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    break;
}
return 0;
}

//-------------------
HANDLE OpenFile(LPCTSTR pFileName)
{
       HANDLE pFile ;
       pFile = CreateFile(pFileName,GENERIC_WRITE,
           FILE_SHARE_READ,NULL,OPEN_ALWAYS        ,
           FILE_ATTRIBUTE_NORMAL ,NULL);
       if(INVALID_HANDLE_VALUE == pFile)
       {
           MessageBox(NULL, "Error","Nie można otworzyć pliku.",MB_OK);
           return NULL;
       }
       return pFile  ;       
}
// ------------------
void StartTime(HANDLE file, LPTSTR FileData)
{
     int timer;
     DWORD len ;
     timer=time(NULL);
     sprintf(FileData,"1|%d\n",timer);
     WriteFile(file,FileData,lstrlen(FileData),&len,NULL);     
}
// ------------------
int EndTime(HANDLE file, LPTSTR FileData)
{
     int timer;
     DWORD len ;
     timer=time(NULL);
     sprintf(FileData,"0|%d\n",timer);
     WriteFile(file,FileData,lstrlen(FileData),&len,NULL);  
     return lstrlen(FileData);
}

mam nadzieje że wszystko ok bo chodzić chodzi :)

0

a nie prościej napisać program przeglądający logi systemowe w poszukiwaniu zdarzeń startu i zamykania systemu?

poza tym, pozostający przy koncepcji własnego programu nasłuchującego na odp. zdarzenia, powinien imho on pracować raczej jako usługa.

0

hmmmm... zastanawiałem sie przez jakiś czas nad usługą ale to co jest napisane na msdn'ie jakoś do mnie nie przemawia (wole jakoś rzeczy wytłumaczone krok po kroku a nie gotowy kod do interpretacji własnej). Jak patrzyłem na forum to za bardzo nie był poruszany temat usług. Jak by ktoś znał tutorial opisujący usługi był bym wdzięczny za linka albo też tytuł książki opisującej to.
PS:
Byle by to był język PL/ENG

Pozdrawiam!

0

Hym , usługa - a w jakim celu ?

0

oj dzejo, w takim celu, żeby szpanersko było ;]
Usługa... generalnie programy działające w tle, jakich używam, albo nie są usługami, albo mogą ruszać jako service opcjonalnie.

Warto też dodać, że z tego, co przeczytałem, nie trzeba pisać programu specjalnie jako usługi. Wystarczy sobie napisać program zwyczajnie i później go sobie jako usługę owrappować i zainstalować. Tutaj jest o tym:

przewinąć do posta #18, mi adres bezpośredni do posta nie chce załapać
0

Ale przecież windows sam log'uje wszystkie operacje typu włączenie, wyłączenie kompa itp, tak więc najlepiej będzie odpowiednio zinterpretować logi. Tego typu programiki, jakie piszesz łatwo jest oszukać.

0

a logi systemowe dobrzy uzytkownicy komputerow czasem czyszcza :)

0
quetzalcoatl napisał(a)

a logi systemowe dobrzy uzytkownicy komputerow czasem czyszcza :)
Jak mają uprawnienia :)

0

Hym , usługa - a w jakim celu ?
też mi się tak wydaje :)

oj dzejo, w takim celu, żeby szpanersko było ;]
szpanersko nie szpanersko ma być prosto bo skomplikowane rzeczy mają taka własność, że lubią nawalać :)

Czyli tak jak było powiedziane na początku, najlepsze jest nie widoczne okno?

Pozdrawiam

0

Tak , tylko pytam , dla mnie sprawa jest prosta ( oprócz tych logów [green] ) .

Jeśli aplikacja ma być "legalnie działającym programem dla zwkłego użytkownika"
to niech taką pozostanie , obojętnie czy będzie uruchamiana z Autostart czy z rejestru ,
przeglądała logi systemowe czy inaczej .[ ps. gdzie jest zapisany czas i data trwania sesji np. w XP
, w jakim pliku ?] [ pomijam jawne działania w postaci wywolań np. systeminfo.exe , date, time , sc itp. ]

Jeśli natomiast efekt jej działania ma być dostępny tylko dla "administratora" lub osoby która
chce ukryć jej działanie to warto pobawić sie w programy działające jako usługa systemowa , sterownik,
lub jakiś hook .

ps.Wcześniejszy kod można równie dobrze wrzucić do .dll i wykonywać w sposób który nie wskazuje
na konkretną aplikację , mi przynajmniej wydaje sie to bardziej przejrzyste od grzebania
w jakichś plikach generowanych przez system oraz przetwarzania ich zawartości ,
a w każdym razie ciekawsze ...
@adf88

Tego typu programiki, jakie piszesz łatwo jest oszukać.

to odpowiedz na zapytanie z postu nr 1 koziol i nie jest żadnym super wzorcem kodu który można napisać spełniając przy okazji inne wymagania ..

1 użytkowników online, w tym zalogowanych: 0, gości: 1