Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Алгоритм, время работы 
:(
    Опции темы
Springtime
Дата 12.7.2009, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 221
Регистрация: 25.10.2006
Где: Россия, Тюмень

Репутация: 0
Всего: 2



Всем привет.
Помогите пожалуйста решить мега-задачу.

в общем делаю прогу которая должна собирать время работы с окном в винде. То есть сколько пользователь работает в том или ином окне и скидывает данные на SQL.
сама функция - 
Код

private Inf GetWindow()
        {
            Inf inf = new Inf();
            handle = GetForegroundWindow();
            GetWindowText(handle, STR, 256);
            inf.startTime = DateTime.Now;
            GetWindowThreadProcessId(handle, out lpwdProcessId);
            process = Process.GetProcessById((int)lpwdProcessId);
            inf.prcName = process.ProcessName;
            inf.MachineName = System.Environment.MachineName.ToString();
            inf.userName = System.Environment.UserName.ToString();
            inf.banner = STR.ToString();
            inf.handle = int.Parse(handle.ToString());
            return inf;
        }

возвращает структуру

Код

struct Inf
    {
        public string prcName;
        public string userName;
        public string MachineName;
        public DateTime startTime;
        public DateTime endTime;
        public string banner;
        public int handle;
    }


проблема в том что никак не могу допереть как её организовать, то есть как сделать что бы она вычисляла время работы с окном и данные скидывала сразу же после смены окна (как скидывала это понятно). 
У нас есть начальное время, это хорошо, но как вычислить время конечно время, причём это время мы не должны браться из начального времени нового окна. 
Заранее спасибо.
--------------------
ICQ: 1fe410f46e7f48f6c721bc866d8294a2
PM MAIL ICQ   Вверх
Экскалупатор
Дата 12.7.2009, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



есть структура TimeSpan которая хранит интервал времени, т.е. не начало и конец, а сколько прошло. обрабатываешь событие окна в начале когда окно получает фокус, в конце когда окно фокус теряет, вычитаешь первое из последнего и разницу записываешь. в базу записываешь тоже по событию потери фокуса окном.
про TimeSpan
PM MAIL ICQ   Вверх
Springtime
Дата 12.7.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 221
Регистрация: 25.10.2006
Где: Россия, Тюмень

Репутация: 0
Всего: 2



Не совсем то что нужно. Про TimeSpan знаю. Извиняюсь что не совсем прозрачно рассказал.
Конечное время не должно браться из начального времени нового окна. Т.к. есть перерывы на обед.

В общем вот полностью примерный код. Очень прошу помочь.

Код

namespace Life
{
    class Leader : ApplicationContext
    {
        InfoTimeClass InfTime = new InfoTimeClass(); // Создание рабочего класса

        public Leader()
        {
            Initialize();
        }
        public void Initialize()
        {
            TimeProg(); //Инициализация таймера
        } 

        private void TimeProg()
        {
            System.Timers.Timer timer1 = new System.Timers.Timer();
            timer1.Enabled = true;
            timer1.Interval = 1000;
            timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
        }

        private void timer1_Elapsed(object sender, EventArgs e) //Событие таймера
        {
            InfTime.huiznaet(); // Главная функция рабочего класса
        }
    }

    class InfoTimeClass //Сам рабочий класс
    {
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hwnd, StringBuilder bld, int size);
        IntPtr handle;
        uint lpwdProcessId;
        Process process;
        StringBuilder STR = new StringBuilder(256);

        private Inf GetWindow()
        {
            Inf inf = new Inf();
            handle = GetForegroundWindow();
            GetWindowText(handle, STR, 256);
            inf.startTime = DateTime.Now;
            GetWindowThreadProcessId(handle, out lpwdProcessId);
            process = Process.GetProcessById((int)lpwdProcessId);
            inf.prcName = process.ProcessName;
            inf.MachineName = System.Environment.MachineName.ToString();
            inf.userName = System.Environment.UserName.ToString();
            inf.banner = STR.ToString();
            inf.handle = int.Parse(handle.ToString());
            return inf;
        }

        private void SqlSend(InfoTime info) //Скидываем данные
        {
            using (SqlConnection connection = new SqlConnection("Server=BIOHAZARD-ПК\\SQL2008;Database=ProgramLog;Integrated Security=true;"))
            {
                SqlCommand command = new SqlCommand("INSERT INTO LifeJob (Computer, CurrentUser, NameProcess, Banner, StartDataTimeProcess, EndDataTimeProcess) VALUES ('" + info.MachineName + "','" + info.userName + "','" + info.prcName + "','" + info.banner + "','" + info.startTime.ToString("yyy-MM-d HH:mm:ss") + "','" + info.endTime.ToString("yyy-MM-d HH:mm:ss") + "')", connection);
                connection.Open();
                int numrows = command.ExecuteNonQuery();
            }
        }

        public void huiznaet()
        {
            Inf inf = new Inf();
            inf = GetWindow();
            // Тут не совсем понятно что делать. То есть как мы отслеживаем смену окна, храним промежуточное значение.
        }
    }

    public struct InfoTime
    {
        public string prcName;
        public string userName;
        public string MachineName;
        public DateTime startTime;
        public DateTime endTime;
        public string banner;
        public int handle;
    }
    public struct Inf
    {
        public string prcName;
        public string userName;
        public string MachineName;
        public DateTime startTime;
        public string banner;
        public int handle;
    }
}


Это сообщение отредактировал(а) Springtime - 12.7.2009, 14:21
--------------------
ICQ: 1fe410f46e7f48f6c721bc866d8294a2
PM MAIL ICQ   Вверх
neutrino
Дата 13.7.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: 3
Всего: 62



Мне задача не до конца ясна. Если надо именно время работы за окном, то надо ловить ивенты нажатия/движения мыши и проверять активно ли окно. Если да, то все еще считаем время. Тогда мне не понятно в чем трудность? Наверное, я что-то упустил.
Цитата(Springtime @  12.7.2009,  13:20 Найти цитируемый пост)
Конечное время не должно браться из начального времени нового окна.

А что есть конец использования окна? 


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
Экскалупатор
Дата 13.7.2009, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



Springtime, повторюсь, у формы есть события Focus, так вот засекаем первое время когда Form1_Activated(когда окно попадает в фокус), второе время засекаем когда Form1_Deactivate(т.е. когда окно теряет фокус, это будет происходить всегда когда пользователь будет кликать мышкой(или переключаться иными способами)на других окошках, рабочем столе и т.п.) потом вычитаем из второго времени первое и получаем цифру равную количеству времени, когда окно было активно(т.е. было в фокусе). никаких 
Цитата

Конечное время не должно браться из начального времени нового окна.

тут не будет, все привязывается к одному окну. в результате получаем TimeSpan который и записываем в базу.

Это сообщение отредактировал(а) Экскалупатор - 13.7.2009, 20:03
PM MAIL ICQ   Вверх
Springtime
Дата 14.7.2009, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 221
Регистрация: 25.10.2006
Где: Россия, Тюмень

Репутация: 0
Всего: 2



Цитата(neutrino @ 13.7.2009,  14:54)
А что есть конец использования окна?

время завершения работы с окном - есть время начала с работы новым окном

Экскалупатор мне время работы с окном (TimeSpan) не нужно, мне необходимо время начала работы с ним и время завершения работы с ним. То есть время завершения отсчитывается пока не сменился хендл у окна.

В нынешнем варианте время завершения работы с окном - есть время начала с работы новым окном (с новым хендлом). Но проблема в том что есть обеды, во время начала которого мы должны прерывать время работы с окном. То есть допустим окно активировано в 12:50, обед у нас c 13:00-14:00. Функция опрашивает раз в секунду, не сменилось ли окно, если сменилось то отправляем данные. Идёт проверка не наступил ли по времени 13 (время обеда). Если наступило, то опрос больше не происходит. Следующее начало опроса в 14. Но у нас тогда выходит что время начала с окном 12:50 (далее наступает пауза с 13 до 14) и если пользователь сменил окно во время обеда, то время завершения работы с окном 14:00. А надо что бы время завершения было 12:59.

Код

 class ClassOne : ApplicationContext
    {
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hwnd, StringBuilder bld, int size);

        IntPtr handle;
        uint lpwdProcessId;
        Process process;
        info wnd = new info();
        StringBuilder STR = new StringBuilder(256);

        public string InfoSQL()
        {
            String sqlconn="";
            try
            {
                sqlconn = ConfigurationManager.ConnectionStrings["LifeCodeServiceLog"].ConnectionString;
            }
            catch (NullReferenceException)
            {
                System.Windows.Forms.MessageBox.Show("Не найден конфигурационный файл.");
                Process currentPr = Process.GetCurrentProcess();
                currentPr.Kill();
            }
            return sqlconn;
        }
        public ClassOne()
        {
            Initialize();
        }
        public void Initialize()
        {
            NonTwoStart();
            wnd = GetWindow();
            System.Timers.Timer timer1 = new System.Timers.Timer();
            timer1.Enabled = true;
            timer1.Interval = 1000;
            timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
        }
        private void timer1_Elapsed(object sender, EventArgs e)
        {
            if (ShudlTime()) // Проверка, рабочее время или нет
            {
                PrcChg(GetWindow());
            }
        }
        public struct info
        {
            public string prcName;
            public string userName;
            public string MachineName;
            public DateTime startTime;
            public DateTime endTime;
            public string banner;
            public int handle;
        }
        public struct infownd
        {
            public string prcName;
            public string userName;
            public string MachineName;
            public DateTime endTime;
            public DateTime StartTime;
            public string banner;
        }
        public void LogMessage(infownd Msg)
        {
                SqlConnection connection = null;
                SqlCommand command = null;
            using(connection = new SqlConnection(InfoSQL()))
            {
                command = new SqlCommand("INSERT INTO ProgrammJob (Computer, CurrentUser, NameProcess, Banner, StartDataTimeProcess, EndDataTimeProcess) VALUES ('" + Msg.MachineName + "','" + Msg.userName + "','" + Msg.prcName + "','" + Msg.banner + "','" + Msg.StartTime.ToString("yyy-MM-d HH:mm:ss") + "','" + Msg.endTime.ToString("yyy-MM-d HH:mm:ss") + "')", connection);
                connection.Open();
                int numrows = command.ExecuteNonQuery();
            }
        }
        public info GetWindow()
        {
            info inf = new info();
            handle = GetForegroundWindow();
            GetWindowText(handle, STR, 256);
            inf.startTime = DateTime.Now;
            GetWindowThreadProcessId(handle, out lpwdProcessId);
            process = Process.GetProcessById((int)lpwdProcessId);
            inf.prcName = process.ProcessName;
            inf.MachineName = System.Environment.MachineName.ToString();
            inf.userName = System.Environment.UserName.ToString();
            inf.banner = STR.ToString();
            inf.handle = int.Parse(handle.ToString());
            return inf;
        }
        public void PrcChg(info window)
        {
            infownd infwnd = new infownd();
            if (wnd.handle != window.handle)
            {
                infwnd = returnwnd(wnd, window);
                LogMessage(infwnd);
            }
        }
        public infownd returnwnd(info inf, info inf2)
        {
            DateTime dt = new DateTime();
            dt = DateTime.Now;

            infownd infwnd = new infownd();
            infwnd.prcName = inf.prcName;
            infwnd.MachineName = inf.MachineName;
            infwnd.userName = inf.userName;
            infwnd.banner = inf.banner;
            infwnd.StartTime = inf.endTime;
            

            infwnd.endTime = inf2.startTime;

            wnd.endTime = inf2.startTime;
            wnd.MachineName = inf2.MachineName;
            wnd.prcName = inf2.prcName;
            wnd.banner = inf2.banner;
            wnd.userName = inf2.userName;
            wnd.handle = inf2.handle;
            return infwnd;
        }
        public void NonTwoStart()
        {
            // Запрет на повторный запуск
            Process currentPr = Process.GetCurrentProcess();
            foreach (Process pr in Process.GetProcesses())
            {
                if ((pr.ProcessName == currentPr.ProcessName) && (pr.Id != currentPr.Id))
                {
                    currentPr.Kill();
                }
            }
        }
        public bool ShudlTime()
        {
            bool onofftime = false;
            DateTime timerun = new DateTime();
            timerun = DateTime.Now;
            int h = timerun.Hour;
            int m = timerun.Minute;
            if ((h > 7) & (h <= 17))
            {
                    if ((h < 13) | (h > 13))
                    {
                        onofftime = true;
                    }
                }
            return onofftime;
        }
        }


Это сообщение отредактировал(а) Springtime - 14.7.2009, 07:35
--------------------
ICQ: 1fe410f46e7f48f6c721bc866d8294a2
PM MAIL ICQ   Вверх
neutrino
Дата 14.7.2009, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: 3
Всего: 62



Цитата(Springtime @  12.7.2009,  13:20 Найти цитируемый пост)
Конечное время не должно браться из начального времени нового окна.

Цитата(Springtime @  14.7.2009,  06:33 Найти цитируемый пост)
время завершения работы с окном - есть время начала с работы новым окном

 smile  smile  smile

 Хорошо. Предложение Экскалупатора думаю подходит. Единственное, с обедом можно поступить 2-мя способами:
1) в 13:00, если есть открытое окно:
- все делается как будто работа с окном прекращается (может даже окно закрывается). 
- в 14:00 все делается как будто работа с окном начинается (можно открыть окно)
То есть с 13:00 до 14:00 активность пользователя не фиксируется.

2) Если в период обеда пользователь все же проявлял активность, то относится к этому как будто обеда не было.

У меня такое ощущение, что не только я не понимаю задачу, но и ты тоже. Можешь привести здесь use case со сценарием включающем, скажем 3 окна и с обедом. Пользователь переключает окна, закрывает их, открывает и т.д. Думаю из примера сразу станет ясно что где и почем.


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
Экскалупатор
Дата 14.7.2009, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



Цитата

Экскалупатор мне время работы с окном (TimeSpan) не нужно, мне необходимо время начала работы с ним и время завершения работы с ним. То есть время завершения отсчитывается пока не сменился хендл у окна.


так разве я не это предложил?

Цитата

у формы есть события Focus, так вот засекаем первое время когда Form1_Activated(когда окно попадает в фокус), второе время засекаем когда Form1_Deactivate(т.е. когда окно теряет фокус, это будет происходить всегда когда пользователь будет кликать мышкой(или переключаться иными способами)на других окошках, рабочем столе и т.п.)


не надо TimeSpan так не высчитывайте его. у вас есть событие начала работы с окном(Form1_Activated) и событие окончания работы с окном(Form1_Deactivate)
пишите в обработчике что то типа
Код

private void Form1_Activated(object sender, EventArgs e)
        {
            DateTime startTime = new DateTime();
            startTime = DateTime.Now;//Получаем время начала работы с окном
        }

и будет вам счастье
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0672 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.