Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Kant
 Аватар для Kant
32 / 32 / 9
Регистрация: 15.05.2013
Сообщений: 223
09.01.2017, 18:01     Получение списка программ понажатию клавиши win #1
Эта тема была поднята несколько раз 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2017, 18:01     Получение списка программ понажатию клавиши win
Посмотрите здесь:

Получение текста из списка C++ WinAPI
Глобальные горячие клавиши C++ WinAPI
Получение списка процессов Windows C++ WinAPI
C++ WinAPI Получение списка файлов в определённой папке
Получение списка путей процессов C++ WinAPI
C++ WinAPI Зажатие клавиши
Нажатие и отпускание клавиши C++ WinAPI
Определение нажатия клавиши C++ WinAPI
Не реагирует на нажатие клавиши C++ WinAPI
Получение WinAPI сообщения для экрана блокировки системы и диспетчера задач в Win 8 C++ WinAPI
Вызов, получение списка функций процесса из injection dll C++ WinAPI
Получение списка пользователей (консольного и rdp-сеансов) C++ WinAPI

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 08:44. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru