С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++ и WinAPI

Войти
Регистрация
Восстановить пароль
 
Kant
33 / 33 / 9
Регистрация: 15.05.2013
Сообщений: 236
#1

Получение списка программ понажатию клавиши win - C++ WinAPI

09.01.2017, 18:01. Просмотров 221. Ответов 0
Метки нет (Все метки)

Эта тема была поднята несколько раз svadum 1, 2, 3.
Но ее трудно будет найти в поиске поэтому создал отдельную тему.

Чтобы сразу стало о чем я, то приложил картинку и ссылку на статью.

И так же небольшая статья что это такое.

main.cpp
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <algorithm>
#include <iostream>
 
#include <ctime>
#include <cctype>
 
#include "util.h"
 
 
std::string rot13(std::string text) {
    std::transform(
        begin(text), end(text), begin(text),
        [](char c) -> char {
        if (!std::isalpha(c))
            return c;
        char const pivot = std::isupper(c) ? 'A' : 'a';
        return (c - pivot + 13) % 26 + pivot;
    });
    return text;
}
 
LONG print_log(const std::string& descrptionError, const std::string &hKeyPath, LONG error) {
    std::cerr << descrptionError << "\n";
    std::cerr << "HKEY by path:\n" << hKeyPath << "\n";
    std::cerr << "error = " << error << std::endl;
    return error;
}
 
 
LONG GetUserAssistKeyValues(std::vector<mfu::KeyValue> &values) {
    HKEY hUserAssistKey;
    HKEY hRootKey = HKEY_CURRENT_USER;
    std::string pathUserAssist = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist";
    std::string GUIDWindows7 = "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}";
    std::string fullPathUserAssist = pathUserAssist + "" + GUIDWindows7 + "\\Count";
 
    LONG errorOpenKey = RegOpenKeyExA(hRootKey, fullPathUserAssist.c_str(), 0, KEY_READ, &hUserAssistKey);
    if (ERROR_SUCCESS == errorOpenKey) {
        DWORD countSubKey = 0;
        DWORD countValues = 0;
 
        LONG errorQueryInfo = mfu::QueryInfoKey(hUserAssistKey, &countSubKey, &countValues);
        if (ERROR_SUCCESS == errorQueryInfo) {
            for (DWORD i = 0; i < countValues; ++i) {
                std::string valueName;
                LONG errorValue = mfu::EnumValue(hUserAssistKey, i, valueName);
                if (ERROR_SUCCESS == errorValue) {
                    mfu::KeyValue value;
                    LONG errorValueData = mfu::ValueData(hUserAssistKey, valueName, value);
                    if (ERROR_SUCCESS == errorValueData) {
                        values.push_back(value);
                    }
                    else { return print_log("Error ValueData.", fullPathUserAssist, errorValueData); }
                }
 
                else { return print_log("Error EnumValue.", fullPathUserAssist, errorValue); }
            }
        }
        else { return print_log("Error QueryInfoKey.", fullPathUserAssist, errorQueryInfo); }
 
        RegCloseKey(hRootKey);
 
        return errorOpenKey;
    }
 
    return  print_log("Can't open Key.", fullPathUserAssist, errorOpenKey);
}
 
struct UserAssistEntry {
    tm lastTime;
    int32_t focusCount;
    int32_t focusTime;
 
    int32_t index;
    std::string name;
};
 
bool isTimeEmpty(tm lastTime) {
    return lastTime.tm_hour == 0
        && lastTime.tm_isdst == 0
        && lastTime.tm_mday == 0
        && lastTime.tm_min == 0
        && lastTime.tm_mon == 0
        && lastTime.tm_sec == 0
        && lastTime.tm_wday == 0
        && lastTime.tm_yday == 0
        && lastTime.tm_year == 0;
}
 
std::ostream &operator<<(std::ostream &out, const UserAssistEntry &ua) {
    out << "key:\n" << ua.name << "\n";
    out << "index: " << ua.index << "\n";
    out << "focusCount: " << ua.focusCount << "\n";
    out << "focusTime: " << ua.focusTime << "\n";
 
    if (!isTimeEmpty(ua.lastTime)) {
        char str[26] = { '\0' };
        asctime_s(str, sizeof(str), &ua.lastTime);
        out << "last time:\n" << std::string(str);
    }
 
    out << std::endl;
    return out;
}
 
 
UserAssistEntry to_user_assist(const mfu::KeyValue &keyValue) {
    UserAssistEntry ua;
    ua.lastTime = tm{ 0,0,0,0,0,0,0,0,0 };
    ua.focusCount = -1;
    ua.focusTime = -1;
    ua.name = rot13(keyValue.name);
 
    if (keyValue.data.size() == 72) {
        int32_t count = 0;
        for (int i = 7; i >= 4; --i) {
            count = (count <<= 8) + keyValue.data[i];
        }
        ua.focusCount = count;
 
        int32_t focusTime = 0;
        for (int i = 15; i >= 12; --i) {
            focusTime = (focusTime <<= 8) + keyValue.data[i];
        }
        ua.focusTime = focusTime;
 
        uint64_t windate = 0;
        for (int i = 67; i >= 60; --i) {
            windate = (windate <<= 8) + keyValue.data[i];
        }
 
        if (windate > 0) {
            uint64_t no_nano = windate / 10000000;
            uint64_t unix = no_nano - 11644473600;
 
            time_t t = unix;
            tm timeinfo = tm{ 0,0,0,0,0,0,0,0,0 };
            localtime_s(&timeinfo, &t);
 
            ua.lastTime = timeinfo;
        }
    }
 
    return ua;
}
 
 
int main() {
    try {
        std::cout << "Most Frequent Used Programs for Windows 7" << std::endl;
 
        std::vector<mfu::KeyValue> values;
        LONG errorGUAKV = GetUserAssistKeyValues(values);
        if (ERROR_SUCCESS == errorGUAKV) {
            std::vector<UserAssistEntry> uas;
            size_t index = 0;
            for (auto value : values) {
                UserAssistEntry ua = to_user_assist(value);
                ua.index = index++;
                uas.push_back(ua);
            }
 
            std::sort(uas.begin(), uas.end(), [](const UserAssistEntry &lhs, const UserAssistEntry &rhs) {
                tm ltm = lhs.lastTime;
                tm rtm = rhs.lastTime;
                return mktime(&ltm) > mktime(&rtm);
            });
 
            auto begin = uas.begin();
            auto end = uas.size() >= 10 ? uas.begin() + 10 : uas.end();
            std::for_each(begin, end, [](const UserAssistEntry &ua) {
                if (!isTimeEmpty(ua.lastTime)) {
                    std::cout << ua << std::endl;
                }
            });
 
        }
 
        return errorGUAKV;
    }
    catch (std::exception &e)
    {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
}


util.h
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef MFU_UTIL_H
#define MFU_UTIL_H
 
#include <Windows.h>
#include <string>
#include <vector>
 
namespace mfu {
    
    typedef unsigned char BYTE;
    typedef std::vector<BYTE> BYTES;
    struct KeyValue {
        DWORD type;
        std::string name;
        BYTES data;
    };
 
    LONG QueryInfoKey(HKEY hKey, LPDWORD countSubKeys, LPDWORD countValues);
 
    LONG EnumValue(HKEY hKey, DWORD index, std::string &valueName);
 
    LONG ValueData(HKEY hKey, const std::string &valueName, KeyValue &valueData);
 
    LONG EnumKey(HKEY hKey, DWORD index, std::string &keyName);
 
} // namespace mfu
 
#endif // MFU_UTIL_H


util.cpp
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "util.h"
 
/*
Key name
255 characters. The key name includes the absolute path of the key in the
registry, always starting at a base key, for example, HKEY_LOCAL_MACHINE.
Value name
16,383 characters
Windows 2000:  260 ANSI characters or 16,383 Unicode characters.
Value   Available memory (latest format)
1 MB (standard format)
Tree    A registry tree can be 512 levels deep. You can create up to 32 levels
at a time through a single registry API call.
*/
static const int MAX_KEY_LENGTH = 255;
 
/*
Registry value names are limited to 32,767 bytes. The ANSI version of this
function treats this parameter as a SHORT value. Therefore, if you specify
a value greater than 32,767 bytes, there is an overflow and the function
may return ERROR_MORE_DATA.
*/
static const int MAX_VALUE_NAME = 16383;
 
namespace mfu {
 
    LONG QueryInfoKey(HKEY hKey, LPDWORD countSubKeys, LPDWORD countValues) {
        TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name
        DWORD    cchClassName = MAX_PATH;        // size of class string
        DWORD    cbMaxSubKey;                    // longest subkey size
        DWORD    cchMaxClass;                    // longest class string
        DWORD    cchMaxValue;                    // longest value name
        DWORD    cbMaxValueData;                 // longest value data
        DWORD    cbSecurityDescriptor;           // size of security descriptor
        FILETIME ftLastWriteTime;                // last write time
 
                                                 // Get the class name and the value count.
        DWORD retCode = RegQueryInfoKey(
            hKey,                    // key handle
            achClass,                // buffer for class name
            &cchClassName,           // size of class string
            NULL,                    // reserved
            countSubKeys,            // number of subkeys
            &cbMaxSubKey,            // longest subkey size
            &cchMaxClass,            // longest class string
            countValues,             // number of values for this key
            &cchMaxValue,            // longest value name
            &cbMaxValueData,         // longest value data
            &cbSecurityDescriptor,   // security descriptor
            &ftLastWriteTime);       // last write time
 
        return retCode;
    }
 
    LONG EnumValue(HKEY hKey, DWORD index, std::string &valueName) {
        DWORD lenFileName = MAX_VALUE_NAME;
        char valueNameBuf[MAX_VALUE_NAME] = { '\0' };
        LONG errorValue = RegEnumValueA(hKey, index, valueNameBuf, &lenFileName, NULL, NULL, NULL, NULL);
        if (ERROR_SUCCESS == errorValue && lenFileName > 0) {
            valueName.reserve(lenFileName);
            valueName = valueNameBuf;
            valueName.shrink_to_fit();
        }
 
        return errorValue;
    }
 
    LONG ValueData(HKEY hKey, const std::string &valueName, KeyValue &value) {
        DWORD sizeValueData = 0;
        DWORD type = RRF_RT_REG_NONE;
        LONG errorQueryValue = RegQueryValueExA(hKey, valueName.c_str(), 0, &type, NULL, &sizeValueData);
        if (ERROR_SUCCESS == errorQueryValue && sizeValueData > 0) {
            LPBYTE valueData = (LPBYTE)malloc(sizeValueData);
            errorQueryValue = RegQueryValueExA(hKey, valueName.c_str(), 0, &type, valueData, &sizeValueData);
            if (ERROR_SUCCESS == errorQueryValue) {
                value.type = type;
                value.name = valueName;
                value.data = BYTES(valueData, valueData + sizeValueData);
            }
            free(valueData);
        }
 
        return errorQueryValue;
    }
 
    LONG EnumKey(HKEY hKey, DWORD index, std::string &keyName) {
        char keyNameBuf[MAX_KEY_LENGTH] = { '\0' };
        LONG errorKey = RegEnumKeyA(hKey, index, keyNameBuf, MAX_KEY_LENGTH);
        if (ERROR_SUCCESS == errorKey) {
            auto lenKeyName = strlen(keyNameBuf);
            keyName.reserve(lenKeyName);
            keyName = keyNameBuf;
            keyName.shrink_to_fit();
        }
 
        return errorKey;
    }
 
} // namespace mfu



Сделал под это дело репозиторий так как есть разные мелочи, которые мог не увидеть. К слову, автор UserAssist Didier Stevens занимался подобной программой продолжительное время с 2006-2012.

PS Дату вытащить оказалось непросто, я забил после пары попыток, но svadum нашел как.

Получение списка программ понажатию клавиши win
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2017, 18:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Получение списка программ понажатию клавиши win (C++ WinAPI):

Получение нажатия клавиши из неактивного окна - C++
Привет всем! Как можно получить нажатую клавишу, если окно приложения не активно?

Получение WinAPI сообщения для экрана блокировки системы и диспетчера задач в Win 8 - C++ WinAPI
Доброе время суток всем. Поискал по форуму подобный вопрос, и похоже что нужного ответа не нашел. ...

Получение текста из списка - C++ WinAPI
Помогите решить следующию проблему. Хочу получить текст из списка. Окно списка я получил (закрыть, зделать невидимым и т.п. могу),...

Получение списка файлов в каталоге - C++
Добрый день. подскажите пожалуйста, как в С++ получить список файлов в каталоге. Делаю так: #include &quot;stdafx.h&quot; #include...

Получение списка путей процессов - C++ WinAPI
Использую vs2010, win7 32. Вообщем,программа выводит список процессов. После получения handle процесса через OpenProcess с правами на...

Получение списка процессов Windows - C++ WinAPI
привет всем! надо написать программу которая управляет процессорами windows для каждого процесса выводит имя,директорию,занимаемая...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2017, 18:01
Привет! Вот еще темы с ответами:

Получение списка файлов в определённой папке - C++ WinAPI
Как получить список всех файлов в определённой папке, включая подпапки, без использования рекурсии. Просто хочется в коде написать...

Получение списка пользователей (консольного и rdp-сеансов) - C++ WinAPI
собственно, необходимо получить список активных пользователей у которых консольный сеанс а так же rdp сеасн с чего начать, не подскажите?

Вызов, получение списка функций процесса из injection dll - C++ WinAPI
Есть ли способ получить каким либо образом список функций, или для этого надо дизассемблировать dll, и найти все адреса? Есть ли какой то...

Авторизация на google и получение списка календарей (под Win) - C++
Всем привет! Есть задачка: нужно авторизоваться в гугле и стянуть список календарей это должно быть приложение под вин думаю исп...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.