Отправка SMS
Для того, чтобы программно отправлять SMS из QLua, или C#, для начала перейдите по этой ссылке. Вы попадете на сайт сервиса "SMS ЦЕНТР"
Нажав на кнопку "РЕГИСТРАЦИЯ В СЕРВИСЕ", Вы увидите форму регистрации, заполните все поля, обязательно укажите свой телефон.
Нажмите на кнопку "Зарегистрироваться".
Затем нажмите на кнопку "Мой кабинет":
Далее, нажмите на ссылку "Подтвердить номер", затем на кнопку "Получить SMS", Вам на телефон придет SMS с кодом, введите его в поле слева от кнопки, и нажмите ниже кнопку "Подтвердить номер"
После этого на Вашем счету появятся 15 подарочных рублей для тестирования.
Цены на отправку SMS вы можете посмотреть в разделе "Мой кабинет".
На этом настройку на данном сайте можно считать завершенной.
Для использования данного сервиса в QLua нужно скачать данный архив, извлечь из него 3 папки: "lua", "mime", "socket". И поместить их в корневой каталог терминала QUIK (туда, где файл info.exe).
1 2 3 4 5 6 7 8 9 10 11 12 | http = require('socket.http'); login = "MyLogin"; -- Ваш логин на сайте smsc.ru password = "MyPassword"; -- Ваш пароль на сайте smsc.ru phone = "79999999999"; -- Ваш номер телефона msg = "Текст сообщения"; function main() message(tostring(http.request ("http://smsc.ru/sys/send.php?login="..login.."&psw="..password.."&phones="..phone.."&mes="..msg))); end; -- Если Вы нигде не ошиблись, то получите SMS на телефон от "SMSC.RU" и сообщение в терминале вида: "OK - 1 SMS, ID - 1" |
http = require('socket.http'); login = "MyLogin"; -- Ваш логин на сайте smsc.ru password = "MyPassword"; -- Ваш пароль на сайте smsc.ru phone = "79999999999"; -- Ваш номер телефона msg = "Текст сообщения"; function main() message(tostring(http.request ("http://smsc.ru/sys/send.php?login="..login.."&psw="..password.."&phones="..phone.."&mes="..msg))); end; -- Если Вы нигде не ошиблись, то получите SMS на телефон от "SMSC.RU" и сообщение в терминале вида: "OK - 1 SMS, ID - 1"
Для отправки SMS из C# перейдите по данной ссылке и скачайте первый файл "smsc_api.cs"
Положите его в папку с Вашим проектом C# (там, где папка bin) и добавьте его в проект, нажав правой кнопкой мыши по названию проекта, перейдя по пути: "Добавить" -> "Существующий элемент...", выбрав данный файл в папке проекта и нажав кнопку добавить.
Далее, нажмите правой кнопкой мыши по ссылке "References" Вашего проекта и выберите "Добавить ссылку...".
В открывшемся окне найдите "System.Web", поставьте галочку слева от него и нажмите на кнопку "ОК".
Теперь необходимый функционал подключен к проекту!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private void button1_Click(object sender, EventArgs e) { SMSC smsc = new SMSC(); // Создает экземпляр класса для работы с сервисом string[] r = smsc.send_sms("79999999999", "Проверочное SMS"); // Отправляет SMS на номер string Result = ""; if(r.Length > 2) // Если ошибки нет { Result += "id = " + r[0] + Environment.NewLine + "количество sms = " + r[1] + Environment.NewLine + "стоимость = " + r[2] + Environment.NewLine + "баланс = " + r[3] + Environment.NewLine; } else // Если ошибка есть { Result += "id = " + r[0] + Environment.NewLine + "код ошибки = " + r[1] + Environment.NewLine; } // Выводит результат MessageBox.Show(Result); } |
private void button1_Click(object sender, EventArgs e) { SMSC smsc = new SMSC(); // Создает экземпляр класса для работы с сервисом string[] r = smsc.send_sms("79999999999", "Проверочное SMS"); // Отправляет SMS на номер string Result = ""; if(r.Length > 2) // Если ошибки нет { Result += "id = " + r[0] + Environment.NewLine + "количество sms = " + r[1] + Environment.NewLine + "стоимость = " + r[2] + Environment.NewLine + "баланс = " + r[3] + Environment.NewLine; } else // Если ошибка есть { Result += "id = " + r[0] + Environment.NewLine + "код ошибки = " + r[1] + Environment.NewLine; } // Выводит результат MessageBox.Show(Result); }
ОТПРАВКА E-MAIL
Для того, чтобы отправить письмо на эл.почту (в т.ч. с прикрепленным файлом) из QLua скачайте архив EmailSender.zip, в нем находятся 2 файла: SenderEmail.dll - библиотека (для Quik 8 x64 используйте эту dll), которая подключается к скрипту QLua и Email.exe - приложение (почтовый клиент), написанное на C#, которое автоматически запускается и завершается и видно только в виде иконки (логотип сайта) в области уведомлений (правый нижний угол рабочего стола Windows). Оба этих файла нужно извлечь из архива и поместить в корневой каталог терминала QUIK (где info.exe).
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 | require("SenderEmail"); -- Подключает SenderEmail.dll Run = true; -- Флаг поддержания работы скрипта -- Основная функция скрипта, пока выполняется она, работает скрипт function main() -- Отправляет письмо SenderEmail.SendEmail( "smtp.mail.ru", -- SMTP сервер "test@mail.ru", -- Ваш логин "MyPassword", -- Ваш пароль "test@mail.ru", -- Email получателя "test@mail.ru", -- Email отправителя "Тема", -- Тема письма "Текст письма", -- Текст письма "Тест.txt" -- Путь к файлу вложения относительно Email.exe, либо полный путь -- (если не нужно, то оставить пустым (""), либо вообще убрать) ); -- !!! Не отправляйте новое письмо, пока не дождетесь результата отправки предыдущего в функции EmailResult() while Run do sleep(10); end; -- Поддерживает работу функции main() end; -- Функция обратного вызова, вызывается автоматически после отправки письма function EmailResult(res) -- Если отправка прошла успешно в res будет "OK", при ошибке "Ошибка отправки email: Текст ошибки" message(res); end; -- Функция вызывается при остановке скрипта function OnStop() Run = false; -- Сбрасывает флаг, чтобы завершить цикл while в функции main() end; |
require("SenderEmail"); -- Подключает SenderEmail.dll Run = true; -- Флаг поддержания работы скрипта -- Основная функция скрипта, пока выполняется она, работает скрипт function main() -- Отправляет письмо SenderEmail.SendEmail( "smtp.mail.ru", -- SMTP сервер "test@mail.ru", -- Ваш логин "MyPassword", -- Ваш пароль "test@mail.ru", -- Email получателя "test@mail.ru", -- Email отправителя "Тема", -- Тема письма "Текст письма", -- Текст письма "Тест.txt" -- Путь к файлу вложения относительно Email.exe, либо полный путь -- (если не нужно, то оставить пустым (""), либо вообще убрать) ); -- !!! Не отправляйте новое письмо, пока не дождетесь результата отправки предыдущего в функции EmailResult() while Run do sleep(10); end; -- Поддерживает работу функции main() end; -- Функция обратного вызова, вызывается автоматически после отправки письма function EmailResult(res) -- Если отправка прошла успешно в res будет "OK", при ошибке "Ошибка отправки email: Текст ошибки" message(res); end; -- Функция вызывается при остановке скрипта function OnStop() Run = false; -- Сбрасывает флаг, чтобы завершить цикл while в функции main() end;
Если у Вас при использовании данного варианта отправки появятся ошибки, или Вы захотите внести какие-то коррективы в код, то можете скачать готовое решение для Visual Studio 2015 и перестроить (скомпилировать) его на своем компьютере.
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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | //SenderEmail.cpp 2015(c)QuikLuaCSharp.ru #include <windows.h> // Подключает основной функционал для работы с ОС Windows #include <thread> // Подключает функционал для работы с потоками #include <tlhelp32.h> // Подключает функционал для получения информации о запущенных процессах //=== Необходимые для Lua константы ============================================================================// #define LUA_LIB #define LUA_BUILD_AS_DLL //=== Заголовочные файлы LUA ===================================================================================// extern "C" { #include "Lua\lauxlib.h" #include "Lua\lua.h" } //=== Получает указатели на выделенную именованную память =====================================================// // Имя для выделенной памяти для отправки Email TCHAR EmailMemory[] = TEXT("EmailMemory"); // Создаст, или подключится к уже созданной памяти с таким именем HANDLE hFileMapEmail = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, EmailMemory); //КОНСТАНТЫ СОСТОЯНИЯ ПАМЯТИ const char *QR = "_QR_"; // Память ожидает чтения Qlua (Qlua Read) const char *QW = "_QW_"; // Память ожидает записи Qlua (Qlua Write) const char *CR = "_CR_"; // Память ожидает чтения C# (C# Read) const char *CW = "_CW_"; // Память ожидает записи C# (C# Write) volatile PBYTE pb = NULL; // Указатель на байты данных памяти TCHAR szPath[] = TEXT("Email.exe"); // Путь почтового клиента STARTUPINFO si; // Необходимые для запуска процесса структуры PROCESS_INFORMATION pi; // bool SMTPclientWasRunning = false; // Флаг, что почтовый клиент уже был запущен ранее, чтобы не запустить еще одну копию // Функция проверяет запущен ли процесс (программа) по его имени bool IsProcessRun(const char * const processName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); Process32First(hSnapshot, &pe); while (1) { if (strcmp(pe.szExeFile, processName) == 0) return true; if (!Process32Next(hSnapshot, &pe)) return false; } } //=== Стандартная точка входа для DLL ==========================================================================// BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { //Каждому событию соответствует свое значение аргумента fdwReason, передаваемого функции DllMain при его возникновении switch (fdwReason) { case DLL_PROCESS_ATTACH: // Подключение DLL // Если почтовый клиент еще не запущен if (!IsProcessRun("Email.exe")) { //Запускает почтовый клиент memset(&si, 0, sizeof(si)); si.cb = sizeof(si); memset(&pi, 0, sizeof(pi)); CreateProcess(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); } else { SMTPclientWasRunning = true; // Запоминает, что почтовый клиент уже был запущен (до подключения данной DLL) } return TRUE; case DLL_PROCESS_DETACH: // Отключение DLL // Если почтовый клиент был запущен данной DLL if (!SMTPclientWasRunning) { //Закрывает почтовый клиент TerminateProcess(pi.hProcess, 0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } break; case DLL_THREAD_ATTACH: // Создание нового потока break; case DLL_THREAD_DETACH: // Завершение потока break; } return TRUE; } //=== Вспомогательные функции ==================================================================================// //Функции проверки состояний памяти static bool QluaReadReady() // Память ожидает чтения Qlua (Qlua Read) { if (pb[0] == '_' && pb[1] == 'Q' && pb[2] == 'R' && pb[3] == '_') return true; return false; } static bool QluaWriteReady() // Память ожидает записи Qlua (Qlua Write) { if (pb[0] == '_' && pb[1] == 'Q' && pb[2] == 'W' && pb[3] == '_') return true; return false; } //Функция читает память "EmailMemory" с периодичностью в 10 миллисекунд, пока не получит результат отправки email от C#, //затем передает результат в QLua функцию EmailResult(), если она есть в скрипте static int WaitingEmailResult(lua_State *L) { lua_getglobal(L, "EmailResult"); //Находит в стеке Lua функцию по ее названию и помещает ее наверх стека if (lua_isfunction(L, -1)) // Если на верху стека функция { int callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); //Получает индекс функции в специальной внутренней таблице (реестре) Lua // Ждет, пока C# запишет в память результат отправки email (память будет ожидать чтения Qlua) while (!QluaReadReady()) { Sleep(10); } // Пауза в 10 миллисекунд lua_rawgeti(L, LUA_REGISTRYINDEX, callbackRef); // Достает функцию из реестра Lua по ранее полученному индексу и помещает в стек if (lua_isfunction(L, -1)) // Если на верху стека функция { lua_pushstring(L, (char*)(pb + 4)); //Записывает в Lua-стек полученный результат (без управляющей константы) lua_call(L, 1, 1); //Вызывает выбранную функцию в скрипте QLua, передавая в нее 1 параметр (L - стек, 1 - количество передаваемых параметров, 1 - количество возвращаемых значений(нужно, чтобы обновлять стек)) } //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; // Устанавливает константу "_QW_", сообщая тем самым, что память ожидает записи QLua memcpy(pb, QW, 4); } //Закрывает представление UnmapViewOfFile(pb); return (0); //Выход из функции } //=== Реализация функций, вызываемых из LUA ====================================================================// // Получает строку Email информации и отправляет ее в C# static int forLua_SendEmail(lua_State *L) { //Если указатель на память получен if (hFileMapEmail) { // Получает доступ (представление) непосредственно к чтению/записи байт pb = (PBYTE)(MapViewOfFile(hFileMapEmail, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 4096)); // Если доступ получен if (pb != NULL) { lua_getglobal(L, "EmailResult"); //Находит в стеке Lua функцию по ее названию и помещает ее наверх стека int callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); //Получает индекс функции в специальной внутренней таблице (реестре) Lua //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; //Сообщает приложению C# о готовности отправить письмо memcpy(pb, "Q_READY", 7); //Ждет ответа от C# не более 3-х секунд // Получает время в миллисекундах, прошедших с запуска ОС unsigned long long TickCount = GetTickCount(); while (true) { //Проверяет ответ о готовности от C# (ответом является "_QW_") if (QluaWriteReady()) { break;//Выходит из цикла для отправки письма } else { //Проверяет задержку if (GetTickCount() - TickCount >= 3000) { //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; //Сообщает о невозможности отправки lua_rawgeti(L, LUA_REGISTRYINDEX, callbackRef); // Достает функцию из реестра Lua по ранее полученному индексу и помещает в стек lua_pushstring(L, "ОШИБКА: Почтовый клиент не запущен !!!"); //Записывает в Lua-стек полученный результат lua_call(L, 1, 0); //Вызывает выбранную функцию в скрипте QLua, передавая в нее 1 параметр (L - стек, 1 - количество передаваемых параметров, 0 - количество возвращаемых значений)) return (0);//Выходит из функции } } Sleep(1); // Пауза 1 миллисекунда } // Считывает из Lua-стека параметры Email-информации и объединяет их в одну строку char EmailInfo[4096] = "EMAIL_INFO;"; strcat(EmailInfo, lua_tostring(L, 1)); //SMTP сервер strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 2)); //Ваш логин strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 3)); //Ваш пароль strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 4)); //Email получателя strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 5)); //Email отправителя strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 6)); //Тема письма strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 7)); //Текст письма if (lua_isstring(L, 8) && lua_tostring(L, 8) != "") // Если есть вложение (путь к файлу) { strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 8)); //Путь к файлу вложения } int Size = 0; // Считает количество символов в строке for (int i = 0; i < 4096; i++) { if (EmailInfo[i] == 0)break; Size++; } memcpy(pb + 4, EmailInfo, Size);// Записывает строку в память, начиная со 5-го байта memcpy(pb, CR, 4);// Устанавливает константу "_CR_", сообщая тем самым, что память записана и ожидает чтения C# std::thread thr(WaitingEmailResult, L); //Запускает выполнение функции в отдельном потоке thr.detach(); //Отсоединяет созданный поток от основного, делая его "фоновым" } } return(0); } //=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================// static struct luaL_reg ls_lib[] = { { "SendEmail", forLua_SendEmail }, { NULL, NULL } }; //=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================// extern "C" LUALIB_API int luaopen_SenderEmail(lua_State *L) { luaL_openlib(L, "SenderEmail", ls_lib, 0); return 0; } |
//SenderEmail.cpp 2015(c)QuikLuaCSharp.ru #include <windows.h> // Подключает основной функционал для работы с ОС Windows #include <thread> // Подключает функционал для работы с потоками #include <tlhelp32.h> // Подключает функционал для получения информации о запущенных процессах //=== Необходимые для Lua константы ============================================================================// #define LUA_LIB #define LUA_BUILD_AS_DLL //=== Заголовочные файлы LUA ===================================================================================// extern "C" { #include "Lua\lauxlib.h" #include "Lua\lua.h" } //=== Получает указатели на выделенную именованную память =====================================================// // Имя для выделенной памяти для отправки Email TCHAR EmailMemory[] = TEXT("EmailMemory"); // Создаст, или подключится к уже созданной памяти с таким именем HANDLE hFileMapEmail = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, EmailMemory); //КОНСТАНТЫ СОСТОЯНИЯ ПАМЯТИ const char *QR = "_QR_"; // Память ожидает чтения Qlua (Qlua Read) const char *QW = "_QW_"; // Память ожидает записи Qlua (Qlua Write) const char *CR = "_CR_"; // Память ожидает чтения C# (C# Read) const char *CW = "_CW_"; // Память ожидает записи C# (C# Write) volatile PBYTE pb = NULL; // Указатель на байты данных памяти TCHAR szPath[] = TEXT("Email.exe"); // Путь почтового клиента STARTUPINFO si; // Необходимые для запуска процесса структуры PROCESS_INFORMATION pi; // bool SMTPclientWasRunning = false; // Флаг, что почтовый клиент уже был запущен ранее, чтобы не запустить еще одну копию // Функция проверяет запущен ли процесс (программа) по его имени bool IsProcessRun(const char * const processName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); Process32First(hSnapshot, &pe); while (1) { if (strcmp(pe.szExeFile, processName) == 0) return true; if (!Process32Next(hSnapshot, &pe)) return false; } } //=== Стандартная точка входа для DLL ==========================================================================// BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { //Каждому событию соответствует свое значение аргумента fdwReason, передаваемого функции DllMain при его возникновении switch (fdwReason) { case DLL_PROCESS_ATTACH: // Подключение DLL // Если почтовый клиент еще не запущен if (!IsProcessRun("Email.exe")) { //Запускает почтовый клиент memset(&si, 0, sizeof(si)); si.cb = sizeof(si); memset(&pi, 0, sizeof(pi)); CreateProcess(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); } else { SMTPclientWasRunning = true; // Запоминает, что почтовый клиент уже был запущен (до подключения данной DLL) } return TRUE; case DLL_PROCESS_DETACH: // Отключение DLL // Если почтовый клиент был запущен данной DLL if (!SMTPclientWasRunning) { //Закрывает почтовый клиент TerminateProcess(pi.hProcess, 0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } break; case DLL_THREAD_ATTACH: // Создание нового потока break; case DLL_THREAD_DETACH: // Завершение потока break; } return TRUE; } //=== Вспомогательные функции ==================================================================================// //Функции проверки состояний памяти static bool QluaReadReady() // Память ожидает чтения Qlua (Qlua Read) { if (pb[0] == '_' && pb[1] == 'Q' && pb[2] == 'R' && pb[3] == '_') return true; return false; } static bool QluaWriteReady() // Память ожидает записи Qlua (Qlua Write) { if (pb[0] == '_' && pb[1] == 'Q' && pb[2] == 'W' && pb[3] == '_') return true; return false; } //Функция читает память "EmailMemory" с периодичностью в 10 миллисекунд, пока не получит результат отправки email от C#, //затем передает результат в QLua функцию EmailResult(), если она есть в скрипте static int WaitingEmailResult(lua_State *L) { lua_getglobal(L, "EmailResult"); //Находит в стеке Lua функцию по ее названию и помещает ее наверх стека if (lua_isfunction(L, -1)) // Если на верху стека функция { int callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); //Получает индекс функции в специальной внутренней таблице (реестре) Lua // Ждет, пока C# запишет в память результат отправки email (память будет ожидать чтения Qlua) while (!QluaReadReady()) { Sleep(10); } // Пауза в 10 миллисекунд lua_rawgeti(L, LUA_REGISTRYINDEX, callbackRef); // Достает функцию из реестра Lua по ранее полученному индексу и помещает в стек if (lua_isfunction(L, -1)) // Если на верху стека функция { lua_pushstring(L, (char*)(pb + 4)); //Записывает в Lua-стек полученный результат (без управляющей константы) lua_call(L, 1, 1); //Вызывает выбранную функцию в скрипте QLua, передавая в нее 1 параметр (L - стек, 1 - количество передаваемых параметров, 1 - количество возвращаемых значений(нужно, чтобы обновлять стек)) } //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; // Устанавливает константу "_QW_", сообщая тем самым, что память ожидает записи QLua memcpy(pb, QW, 4); } //Закрывает представление UnmapViewOfFile(pb); return (0); //Выход из функции } //=== Реализация функций, вызываемых из LUA ====================================================================// // Получает строку Email информации и отправляет ее в C# static int forLua_SendEmail(lua_State *L) { //Если указатель на память получен if (hFileMapEmail) { // Получает доступ (представление) непосредственно к чтению/записи байт pb = (PBYTE)(MapViewOfFile(hFileMapEmail, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 4096)); // Если доступ получен if (pb != NULL) { lua_getglobal(L, "EmailResult"); //Находит в стеке Lua функцию по ее названию и помещает ее наверх стека int callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); //Получает индекс функции в специальной внутренней таблице (реестре) Lua //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; //Сообщает приложению C# о готовности отправить письмо memcpy(pb, "Q_READY", 7); //Ждет ответа от C# не более 3-х секунд // Получает время в миллисекундах, прошедших с запуска ОС unsigned long long TickCount = GetTickCount(); while (true) { //Проверяет ответ о готовности от C# (ответом является "_QW_") if (QluaWriteReady()) { break;//Выходит из цикла для отправки письма } else { //Проверяет задержку if (GetTickCount() - TickCount >= 3000) { //Очищает память for (int i = 0; i < 4096; i++)pb[i] = '\0'; //Сообщает о невозможности отправки lua_rawgeti(L, LUA_REGISTRYINDEX, callbackRef); // Достает функцию из реестра Lua по ранее полученному индексу и помещает в стек lua_pushstring(L, "ОШИБКА: Почтовый клиент не запущен !!!"); //Записывает в Lua-стек полученный результат lua_call(L, 1, 0); //Вызывает выбранную функцию в скрипте QLua, передавая в нее 1 параметр (L - стек, 1 - количество передаваемых параметров, 0 - количество возвращаемых значений)) return (0);//Выходит из функции } } Sleep(1); // Пауза 1 миллисекунда } // Считывает из Lua-стека параметры Email-информации и объединяет их в одну строку char EmailInfo[4096] = "EMAIL_INFO;"; strcat(EmailInfo, lua_tostring(L, 1)); //SMTP сервер strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 2)); //Ваш логин strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 3)); //Ваш пароль strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 4)); //Email получателя strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 5)); //Email отправителя strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 6)); //Тема письма strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 7)); //Текст письма if (lua_isstring(L, 8) && lua_tostring(L, 8) != "") // Если есть вложение (путь к файлу) { strcat(EmailInfo, ";"); strcat(EmailInfo, lua_tostring(L, 8)); //Путь к файлу вложения } int Size = 0; // Считает количество символов в строке for (int i = 0; i < 4096; i++) { if (EmailInfo[i] == 0)break; Size++; } memcpy(pb + 4, EmailInfo, Size);// Записывает строку в память, начиная со 5-го байта memcpy(pb, CR, 4);// Устанавливает константу "_CR_", сообщая тем самым, что память записана и ожидает чтения C# std::thread thr(WaitingEmailResult, L); //Запускает выполнение функции в отдельном потоке thr.detach(); //Отсоединяет созданный поток от основного, делая его "фоновым" } } return(0); } //=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================// static struct luaL_reg ls_lib[] = { { "SendEmail", forLua_SendEmail }, { NULL, NULL } }; //=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================// extern "C" LUALIB_API int luaopen_SenderEmail(lua_State *L) { luaL_openlib(L, "SenderEmail", ls_lib, 0); return 0; }
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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | //Почтовый клиент 2015(c)QuikLuaCSharp.ru using System; using System.ComponentModel; using System.IO; using System.IO.MemoryMappedFiles; using System.Net; using System.Net.Mail; using System.Threading; using System.Windows.Forms; namespace Email { public partial class Form1 : Form { public static SmtpClient Client; // Выделенная именованная память public static MemoryMappedFile EmailMemory; // Объекты для чтения из памяти public static StreamReader SR_EmailMemory; // Объекты для записи в память public static StreamWriter SW_EmailMemory; //КОНСТАНТЫ СОСТОЯНИЯ ПАМЯТИ const string QR = "_QR_"; // Память ожидает чтения Qlua (Qlua Read) const string QW = "_QW_"; // Память ожидает записи Qlua (Qlua Write) const string CR = "_CR_"; // Память ожидает чтения C# (C# Read) const string CW = "_CW_"; // Память ожидает записи C# (C# Write) public static bool EmailRun = true; // Флаг работы приложения public static bool EmailSending = false; // Флаг, что идет отправка email public Form1() { InitializeComponent(); // Создаст, или подключится к уже созданной памяти с таким именем EmailMemory = MemoryMappedFile.CreateOrOpen("EmailMemory", 4096, MemoryMappedFileAccess.ReadWrite); // Создает потоки для чтения SR_EmailMemory = new StreamReader(EmailMemory.CreateViewStream(), System.Text.Encoding.Default); // Создает потоки для записи SW_EmailMemory = new StreamWriter(EmailMemory.CreateViewStream(), System.Text.Encoding.Default); // Запускает функцию, которая в отдельном потоке ждет команды от QLua на отправку email GettingEmailInfo(); } //Считывает информацию из памяти "EmailMemory" public string GetEmailInfo() { string EmailInfo = ""; //Ждет от DLL сообщения о готовности отправить email ("Q_READY") while(EmailRun) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти, обрезая нули и др. сервисные символы EmailInfo = SR_EmailMemory.ReadToEnd().Trim('\0', '\r', '\n'); // Если пришло сообщение о готовности, выходит из цикла для дальнейших действий if (EmailInfo == "Q_READY") break; Thread.Sleep(10); // Пауза в 10 миллисекунд, чтобы не перегружать процессор } if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_QW_", означающую, что память ожидает записи QLua SW_EmailMemory.Write(QW); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Выполняет цикл, пока память не готова для чтения C# while (EmailInfo.Length == 0 || EmailInfo.Length < 4 || (EmailInfo.Length >= 4 && EmailInfo.Substring(0, 4) != CR)) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти, обрезая нули и др. сервисные символы EmailInfo = SR_EmailMemory.ReadToEnd().Trim('\0', '\r', '\n'); Thread.Sleep(10); // Пауза в 10 миллисекунд, чтобы не перегружать процессор if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс } if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_CW_", означающую, что память ожидает записи C# SW_EmailMemory.Write(CW); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Возвращает то, что прочитано, без управляющей константы return EmailInfo.Substring(4); } // Функция постоянно читает данные из памяти "EmailMemory" при помощи функции GetEmailInfo public void GettingEmailInfo() { //Запускает функцию получения сервисной информации в отдельном потоке, чтобы приложение откликалось на действия пользователя //Чтобы остановить выполнение данного потока, нужно переменной "EmailRun" присвоить значение "false" new Thread(() => // Создает новый поток { string EmailInfo = ""; string[] EmailInfoParts; //Постоянный цикл в отдельном потоке while (EmailRun) { if (EmailSending) {Thread.Sleep(1); continue; } // Если в данный момент выполняется отправка email-сообщения, то ждет завершения //Получает сервисную информацию из памяти, если ее нет, то ждет EmailInfo = GetEmailInfo(); // Разделяет полученную строку на элементы EmailInfoParts = EmailInfo.Split(';'); if (EmailInfoParts.Length > 1 && EmailInfoParts[0] == "EMAIL_INFO")// Если получены данные для отправки письма { //Отправляет письмо Send(EmailInfoParts); } //Чтобы процесс не "забивал" одно из ядер процессора на 100% нужна пауза в 10 миллисекунд Thread.Sleep(10); } }).Start(); // Запускает поток } // Отправляет email private void Send(string[] EmailInfoParts) { string Server = EmailInfoParts[1]; // Сервер string Login = EmailInfoParts[2]; // Логин string Password = EmailInfoParts[3]; // Пароль string To = EmailInfoParts[4]; // Кому string From = EmailInfoParts[5]; // От кого string Subject = EmailInfoParts[6]; // Тема string Body = EmailInfoParts[7]; // Текст письма string Attachment = (EmailInfoParts.Length == 9) ? EmailInfoParts[8] : ""; // Полный, или относительный путь к файлу вложения (если есть) EmailSending = true; // Устанавливает флаг, что началась отправка email, чтобы не инициировать новую try // Пытается выполнить блок кода { Client = new SmtpClient(Server); // Инициализирует новый экземпляр класса SmtpClient, который отправляет электронную почту с помощью указанного сервера SMTP MailAddress from = new MailAddress(From); // От кого MailAddress to = new MailAddress(To); // Кому MailMessage message = new MailMessage(from, to); // Содает объект сообщения message.Body = Body; // Добавляет к сообщению текст message.BodyEncoding = System.Text.Encoding.UTF8; // Устанавливает кодировку для текста сообщения message.Subject = Subject; // Добавляет к сообщению тему message.SubjectEncoding = System.Text.Encoding.UTF8; // Устанавливает кодировку для темы сообщения if (Attachment != "") // Если есть вложение (файл) { Attachment data = new Attachment(Attachment); // Создает объект вложения message.Attachments.Add(data); // Добавляет вложение к сообщению } // Инициализирует новый экземпляр класса NetworkCredential с заданными значениями пароля и имени пользователя Client.Credentials = new NetworkCredential(Login, Password); // Указывает, использует ли SmtpClient протокол SSL для шифрования подключения Client.EnableSsl = true; // Происходит после завершения асинхронной операции по отправке электронной почты (регистрирует функцию обратного вызова) Client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); // Отправляет указанное сообщение SMTP-серверу для доставки в качестве асинхронной операции Client.SendAsync(message, null); } catch (Exception ex) // Если при выполнении блока кода после try произошла ошибка { SetMemoryResult("Ошибка отправки email: " + ex.ToString()); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } } //Функция записывает в память результат отправки email private static void SetMemoryResult(string Result) { string S = ""; // Ожидает в цикле разрешения на запись в память while (EmailRun) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти S = SR_EmailMemory.ReadToEnd(); // Если память ожидает записи C#, выходит из цикла while, иначе ждет 10 миллисекунд if (S.Length > 0 && S.Substring(0, 4) == CW) break; else Thread.Sleep(10); } // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_QR_", означающую, что память ожидает чтения QLua и далее записывает саму команду SW_EmailMemory.Write(QR + Result); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); } // Функция вызывается по окончанию асинхронной отправки почтового сообщения private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { if (e.Error != null) // Если произошла ошибка { SetMemoryResult("Ошибка отправки email: " + e.Error.ToString()); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } else // Отправка прошла без ошибок { SetMemoryResult("OK"); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } } // Функция вызывается при закрытии данного приложения private void Form1_FormClosing(object sender, FormClosingEventArgs e) { notifyIcon1.Visible = false; // Не отображать иконку EmailRun = false; // Сбрасывает флаг работы приложения, чтобы завершился отдельный поток } // Функция вызывается при изменении размеров формы, следовательно, и при сворачивании и разворачивании private void Form1_Resize(object sender, EventArgs e) { if (WindowState == FormWindowState.Minimized) // Если форма свернута { Hide(); // Скрывает форму notifyIcon1.Visible = true; // Отображает иконку в области уведомлений } } // Функция вызывается при клике в контекстном меню, которое появляется при клике правой кнопкой мыши по иконке private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem.Text == "Закрыть") // Если клик по пункту "Закрыть" { Application.Exit(); // Закрывает приложение EmailRun = false; // Сбрасывает флаг работы приложения, чтобы завершился отдельный поток } } } } |
//Почтовый клиент 2015(c)QuikLuaCSharp.ru using System; using System.ComponentModel; using System.IO; using System.IO.MemoryMappedFiles; using System.Net; using System.Net.Mail; using System.Threading; using System.Windows.Forms; namespace Email { public partial class Form1 : Form { public static SmtpClient Client; // Выделенная именованная память public static MemoryMappedFile EmailMemory; // Объекты для чтения из памяти public static StreamReader SR_EmailMemory; // Объекты для записи в память public static StreamWriter SW_EmailMemory; //КОНСТАНТЫ СОСТОЯНИЯ ПАМЯТИ const string QR = "_QR_"; // Память ожидает чтения Qlua (Qlua Read) const string QW = "_QW_"; // Память ожидает записи Qlua (Qlua Write) const string CR = "_CR_"; // Память ожидает чтения C# (C# Read) const string CW = "_CW_"; // Память ожидает записи C# (C# Write) public static bool EmailRun = true; // Флаг работы приложения public static bool EmailSending = false; // Флаг, что идет отправка email public Form1() { InitializeComponent(); // Создаст, или подключится к уже созданной памяти с таким именем EmailMemory = MemoryMappedFile.CreateOrOpen("EmailMemory", 4096, MemoryMappedFileAccess.ReadWrite); // Создает потоки для чтения SR_EmailMemory = new StreamReader(EmailMemory.CreateViewStream(), System.Text.Encoding.Default); // Создает потоки для записи SW_EmailMemory = new StreamWriter(EmailMemory.CreateViewStream(), System.Text.Encoding.Default); // Запускает функцию, которая в отдельном потоке ждет команды от QLua на отправку email GettingEmailInfo(); } //Считывает информацию из памяти "EmailMemory" public string GetEmailInfo() { string EmailInfo = ""; //Ждет от DLL сообщения о готовности отправить email ("Q_READY") while(EmailRun) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти, обрезая нули и др. сервисные символы EmailInfo = SR_EmailMemory.ReadToEnd().Trim('\0', '\r', '\n'); // Если пришло сообщение о готовности, выходит из цикла для дальнейших действий if (EmailInfo == "Q_READY") break; Thread.Sleep(10); // Пауза в 10 миллисекунд, чтобы не перегружать процессор } if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_QW_", означающую, что память ожидает записи QLua SW_EmailMemory.Write(QW); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Выполняет цикл, пока память не готова для чтения C# while (EmailInfo.Length == 0 || EmailInfo.Length < 4 || (EmailInfo.Length >= 4 && EmailInfo.Substring(0, 4) != CR)) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти, обрезая нули и др. сервисные символы EmailInfo = SR_EmailMemory.ReadToEnd().Trim('\0', '\r', '\n'); Thread.Sleep(10); // Пауза в 10 миллисекунд, чтобы не перегружать процессор if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс } if (!EmailRun) return ""; // Если приложение завершается, выходит из функции, чтобы не задерживать процесс // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_CW_", означающую, что память ожидает записи C# SW_EmailMemory.Write(CW); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Возвращает то, что прочитано, без управляющей константы return EmailInfo.Substring(4); } // Функция постоянно читает данные из памяти "EmailMemory" при помощи функции GetEmailInfo public void GettingEmailInfo() { //Запускает функцию получения сервисной информации в отдельном потоке, чтобы приложение откликалось на действия пользователя //Чтобы остановить выполнение данного потока, нужно переменной "EmailRun" присвоить значение "false" new Thread(() => // Создает новый поток { string EmailInfo = ""; string[] EmailInfoParts; //Постоянный цикл в отдельном потоке while (EmailRun) { if (EmailSending) {Thread.Sleep(1); continue; } // Если в данный момент выполняется отправка email-сообщения, то ждет завершения //Получает сервисную информацию из памяти, если ее нет, то ждет EmailInfo = GetEmailInfo(); // Разделяет полученную строку на элементы EmailInfoParts = EmailInfo.Split(';'); if (EmailInfoParts.Length > 1 && EmailInfoParts[0] == "EMAIL_INFO")// Если получены данные для отправки письма { //Отправляет письмо Send(EmailInfoParts); } //Чтобы процесс не "забивал" одно из ядер процессора на 100% нужна пауза в 10 миллисекунд Thread.Sleep(10); } }).Start(); // Запускает поток } // Отправляет email private void Send(string[] EmailInfoParts) { string Server = EmailInfoParts[1]; // Сервер string Login = EmailInfoParts[2]; // Логин string Password = EmailInfoParts[3]; // Пароль string To = EmailInfoParts[4]; // Кому string From = EmailInfoParts[5]; // От кого string Subject = EmailInfoParts[6]; // Тема string Body = EmailInfoParts[7]; // Текст письма string Attachment = (EmailInfoParts.Length == 9) ? EmailInfoParts[8] : ""; // Полный, или относительный путь к файлу вложения (если есть) EmailSending = true; // Устанавливает флаг, что началась отправка email, чтобы не инициировать новую try // Пытается выполнить блок кода { Client = new SmtpClient(Server); // Инициализирует новый экземпляр класса SmtpClient, который отправляет электронную почту с помощью указанного сервера SMTP MailAddress from = new MailAddress(From); // От кого MailAddress to = new MailAddress(To); // Кому MailMessage message = new MailMessage(from, to); // Содает объект сообщения message.Body = Body; // Добавляет к сообщению текст message.BodyEncoding = System.Text.Encoding.UTF8; // Устанавливает кодировку для текста сообщения message.Subject = Subject; // Добавляет к сообщению тему message.SubjectEncoding = System.Text.Encoding.UTF8; // Устанавливает кодировку для темы сообщения if (Attachment != "") // Если есть вложение (файл) { Attachment data = new Attachment(Attachment); // Создает объект вложения message.Attachments.Add(data); // Добавляет вложение к сообщению } // Инициализирует новый экземпляр класса NetworkCredential с заданными значениями пароля и имени пользователя Client.Credentials = new NetworkCredential(Login, Password); // Указывает, использует ли SmtpClient протокол SSL для шифрования подключения Client.EnableSsl = true; // Происходит после завершения асинхронной операции по отправке электронной почты (регистрирует функцию обратного вызова) Client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); // Отправляет указанное сообщение SMTP-серверу для доставки в качестве асинхронной операции Client.SendAsync(message, null); } catch (Exception ex) // Если при выполнении блока кода после try произошла ошибка { SetMemoryResult("Ошибка отправки email: " + ex.ToString()); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } } //Функция записывает в память результат отправки email private static void SetMemoryResult(string Result) { string S = ""; // Ожидает в цикле разрешения на запись в память while (EmailRun) { // Встает в начало потока SR_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Считывает все, что есть в памяти S = SR_EmailMemory.ReadToEnd(); // Если память ожидает записи C#, выходит из цикла while, иначе ждет 10 миллисекунд if (S.Length > 0 && S.Substring(0, 4) == CW) break; else Thread.Sleep(10); } // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Очищает память, заполняя "нулевыми байтами" for (int i = 0; i < 4096; i++) SW_EmailMemory.Write("\0"); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); // Встает в начало потока SW_EmailMemory.BaseStream.Seek(0, SeekOrigin.Begin); // Записывает в начало константу "_QR_", означающую, что память ожидает чтения QLua и далее записывает саму команду SW_EmailMemory.Write(QR + Result); // Очищает все буферы и вызывает запись всех данных буферов в основной поток SW_EmailMemory.Flush(); } // Функция вызывается по окончанию асинхронной отправки почтового сообщения private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { if (e.Error != null) // Если произошла ошибка { SetMemoryResult("Ошибка отправки email: " + e.Error.ToString()); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } else // Отправка прошла без ошибок { SetMemoryResult("OK"); // Записывает в память результат отправки email EmailSending = false; // Сбрасывает флаг (процесс отправки завершен) // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } } // Функция вызывается при закрытии данного приложения private void Form1_FormClosing(object sender, FormClosingEventArgs e) { notifyIcon1.Visible = false; // Не отображать иконку EmailRun = false; // Сбрасывает флаг работы приложения, чтобы завершился отдельный поток } // Функция вызывается при изменении размеров формы, следовательно, и при сворачивании и разворачивании private void Form1_Resize(object sender, EventArgs e) { if (WindowState == FormWindowState.Minimized) // Если форма свернута { Hide(); // Скрывает форму notifyIcon1.Visible = true; // Отображает иконку в области уведомлений } } // Функция вызывается при клике в контекстном меню, которое появляется при клике правой кнопкой мыши по иконке private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem.Text == "Закрыть") // Если клик по пункту "Закрыть" { Application.Exit(); // Закрывает приложение EmailRun = false; // Сбрасывает флаг работы приложения, чтобы завершился отдельный поток } } } }
Если по какой-то причине Вы не можете, или не хотите, использовать Visual Studio 2015, то можете скачать готовое решение для Visual Studio 2010. Данное решение использует библиотеку "BOOST" для C/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 | private void button1_Click(object sender, EventArgs e) { string Server = "smtp.mail.ru"; int Port = 25; string Login = "test@mail.ru"; string Password = "MyPassword"; string To = "test@mail.ru"; // Кому string From = "test@mail.ru"; // От кого string Subject = "Тест SMTP C#"; // Тема string Body = "Тестовое сообщение"; // Текст письма // Инициализирует новый экземпляр класса SmtpClient, который отправляет электронную почту с помощью указанного сервера SMTP и порта SmtpClient Client = new SmtpClient(Server, Port); // Инициализирует новый экземпляр класса NetworkCredential с заданными значениями пароля и имени пользователя Client.Credentials = new NetworkCredential(Login, Password); // Указывает, использует ли SmtpClient протокол SSL для шифрования подключения Client.EnableSsl = true; // Происходит после завершения асинхронной операции по отправке электронной почты (регистрирует функцию обратного вызова) Client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); // Отправляет указанное сообщение SMTP-серверу для доставки в качестве асинхронной операции. //Отправитель, получатели, тема и основная часть сообщения указываются с помощью объектов String Client.SendMailAsync(From, To, Subject, Body); // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } // Функция вызывается по окончанию асинхронной отправки почтового сообщения private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { if (e.Error != null) { MessageBox.Show("Ошибка отправки email: " + e.Error.ToString()); } else { MessageBox.Show("Сообщение email успешно отправлено!"); } } |
private void button1_Click(object sender, EventArgs e) { string Server = "smtp.mail.ru"; int Port = 25; string Login = "test@mail.ru"; string Password = "MyPassword"; string To = "test@mail.ru"; // Кому string From = "test@mail.ru"; // От кого string Subject = "Тест SMTP C#"; // Тема string Body = "Тестовое сообщение"; // Текст письма // Инициализирует новый экземпляр класса SmtpClient, который отправляет электронную почту с помощью указанного сервера SMTP и порта SmtpClient Client = new SmtpClient(Server, Port); // Инициализирует новый экземпляр класса NetworkCredential с заданными значениями пароля и имени пользователя Client.Credentials = new NetworkCredential(Login, Password); // Указывает, использует ли SmtpClient протокол SSL для шифрования подключения Client.EnableSsl = true; // Происходит после завершения асинхронной операции по отправке электронной почты (регистрирует функцию обратного вызова) Client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); // Отправляет указанное сообщение SMTP-серверу для доставки в качестве асинхронной операции. //Отправитель, получатели, тема и основная часть сообщения указываются с помощью объектов String Client.SendMailAsync(From, To, Subject, Body); // Отправляет сообщение QUIT на SMTP-сервер, правильно завершает TCP-подключение и освобождает все ресурсы, используемые текущим экземпляром класса SmtpClient Client.Dispose(); } // Функция вызывается по окончанию асинхронной отправки почтового сообщения private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { if (e.Error != null) { MessageBox.Show("Ошибка отправки email: " + e.Error.ToString()); } else { MessageBox.Show("Сообщение email успешно отправлено!"); } }
Некоторые почтовые сервисы предоставляют оповещение по SMS о новых письмах, по этому, этот способ можно использовать как альтернативное оповещение.
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!