#define _CRT_SECURE_NO_WARNINGS #include "epm_handler_common.h" #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")rename("BOF","adoBOF") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "ws2_32.lib") using namespace std; #define DOFREE(obj) \ { \ if(obj) \ { \ MEM_free(obj); \ obj = NULL; \ } \ } struct Base64Date6 { unsigned int d4 : 6; unsigned int d3 : 6; unsigned int d2 : 6; unsigned int d1 : 6; }; // 协议中加密部分使用的是base64方法 char ConvertToBase64(char c6); void EncodeBase64(char *dbuf, char *buf128, int len); void SendMail(char *email, char *body, char * server_address, int port, char * from_email, char * password); int OpenSocket(struct sockaddr *addr); ////////////////////////////////////////////////////////////////////////////////// //JL_current_touser_mail_address int JL_Send_Mail(EPM_action_message_t msg) { printf("开始执行======JL_Send_Mail\n"); int ifail = ITK_ok; tag_t root_task = NULLTAG; tag_t * attachments = NULLTAG; int count = 0; char * ProcessOwner = NULL; tag_t process_assignee_user = NULLTAG; tag_t process_assignee_person = NULL_TAG; tag_t default_group = NULL_TAG; char * group = NULL; date_t process_creation_date; ::CoInitialize(NULL); //初始化OLE/COM库环境 HRESULT hr = NULL; _ConnectionPtr m_pConnection; // 数据库 _RecordsetPtr m_pRecordset; // 命令 _CommandPtr m_pCommand; // 记录 //邮件属性 char *EmailTo = NULL; //char serverAddress[] = ""; char * server_address = NULL; int port = 25; char * from_email = ""; char * password = ""; char * port_string = NULL; char * ChangeType = NULL; char * ChangeTheOddNumber = NULL; char EmailContents[5120] = ""; char EmailTo1[5120] = ""; //获取首选项 int valueNum = 0; int toEmailNum = 0; char ** to_email = NULL; //PREF_ask_char_value("JL_current_user_server_address", valueNum, &server_address); PREF_ask_char_value("JL_current_user_server_address_port", valueNum, &port_string); PREF_ask_char_value("JL_current_user_mail_password", valueNum, &password); PREF_ask_char_value("JL_current_user_mail_address", valueNum, &from_email); PREF_ask_char_values("JL_current_touser_mail_address", &toEmailNum, &to_email); PREF_ask_char_value("TC11_SqlServer_Link_ITK", valueNum, &server_address); printf("JL_current_user_server_address:%s=======================\n", server_address); port = atoi(port_string); //获取id和名称 char all_ID[5120] = ""; char all_ID_name[512] = ""; char partName[512] = ""; EPM_ask_root_task(msg.task, &root_task); EPM_ask_attachments(root_task, EPM_target_attachment, &count, &attachments); for (int i = 0; i < count; i++) { char * item_id, *object_name, *itemType = NULL; AOM_ask_value_string(attachments[i], "object_type", &itemType); printf("type_class : %s \r\n", itemType); //过滤掉非版本的对象 if((strstr(itemType,"Revision") == NULL) || (strstr(itemType,"Master") != NULL) || (strstr(itemType,"master") != NULL) || (strstr(itemType,"BOM") != NULL) || (strstr(itemType,"bom") != NULL) || (strstr(itemType,"Bom") != NULL)) { continue; } if(strstr(itemType,"ChangeRevision") == NULL){ continue; } AOM_ask_value_string(attachments[i], "item_id", &item_id); AOM_ask_value_string(attachments[i], "object_name", &object_name); sprintf_s(all_ID, "%s ", item_id); sprintf_s(all_ID_name, "%s,%s ", item_id, object_name); int relation_num = 0; tag_t * C8RelationModification = NULLTAG; //获取变更零部件和相关零部件下的对象 AOM_ask_value_tags(attachments[i], "Gd6_BGLBJ", &relation_num, &C8RelationModification); for (int j = 0; j < relation_num; j++) { AOM_ask_value_string(C8RelationModification[j], "item_id", &item_id); AOM_ask_value_string(C8RelationModification[j], "object_name", &object_name); sprintf_s(partName, "%s变更零部件:零件ID:%s-零件名称:%s\n ",partName, item_id, object_name, ""); } AOM_ask_value_tags(attachments[i], "Gd6_XGFJ", &relation_num, &C8RelationModification); for (int j = 0; j < relation_num; j++) { AOM_ask_value_string(C8RelationModification[j], "item_id", &item_id); AOM_ask_value_string(C8RelationModification[j], "object_name", &object_name); sprintf_s(partName, "%s相关零部件:零件ID:%s-零件名称:%s\n ",partName, item_id, object_name, ""); } DOFREE(item_id); DOFREE(object_name); DOFREE(itemType); DOFREE(C8RelationModification); } printf("all_ID:%s=======================\n", all_ID); printf("all_ID_name:%s=======================\n", all_ID_name); //获取参数(变更类型、变更单号) TC_argument_list_t * arguments = msg.arguments; int arg_cnt = TC_number_of_arguments(arguments); printf("TC_number_of_arguments %d\n", arg_cnt); char * arg = NULL, *temp_key = NULL, *temp_val = NULL; for (int ii = 0; iiConnectionString = (server_address); printf("\n==========================================================\n"); hr = m_pConnection->Open("", "", "", adConnectUnspecified);//打开数据库 if (FAILED(hr)) { printf("Open Failed!"); return 1; } for (int j = 0; j < valid_signoffs_count; j++) { printf("开始执行发送++++++++\n"); char * assign_user_name = NULL; tag_t assign_user = NULL_TAG; tag_t person = NULL_TAG; tag_t Email = NULL_TAG; //负责人 AOM_ask_value_tag(valid_signoffs_tags[j], "fnd0Assignee", &assign_user); if (assign_user != NULL_TAG) { AOM_UIF_ask_value(assign_user, "user_name", &assign_user_name); AOM_ask_value_tag(assign_user, "person", &person); AOM_ask_value_string_at(person, "PA9", 0, &EmailTo); strcpy_s(EmailTo1, EmailTo); //strncpy(1,2,3); 把2中长度为3的字符串复制入1 strncpy_s(EmailTo1, EmailTo, strlen(EmailTo1) - 2); //sprintf_s(EmailContents, "From: \"%s\"<%s>\r\n To: \"%s\"<%s>\r\n Subject: %s %s 通知(%s)\r\n\r\n %s:\n您好!由%s(部门)%s(人员)发布的%s %s的%s于%s正式发布生效,变更单号为%s。\n请于今日内登录Teamcenter系统查阅具体变更信息!\n操作路径为:打开我的工作列表->查看要执行的任务下的附件。", //ProcessOwner, from_email, assign_user_name, EmailTo, all_ID, ChangeType, ChangeTheOddNumber, assign_user_name, group, ProcessOwner, all_ID, all_ID_name, ChangeType, date_string, partName); sprintf_s(EmailContents, /*"From: \"%s\"<%s>\r\n" "To: \"%s\"<%s>\r\n" "Subject: %s %s 通知(%s)\r\n\r\n"*/ "%s:\n您好!由%s(部门)%s(人员)发布的%s %s的%s,%s,变更单号为%s。" "\n%s" "\n请于今日内登录Teamcenter系统查阅具体变更信息!" "\n操作路径为:在搜索框输入变更单号->查看变更单对象下的附件。", //ProcessOwner, from_email, assign_user_name, EmailTo, all_ID, ChangeType, ChangeTheOddNumber, assign_user_name, group, ProcessOwner, all_ID, all_ID_name, ChangeType, ChangeTheOddNumber, all_ID,partName ); cout<< EmailContents<Execute(_bstr_t(describe), 0, adCmdText); //return 1;//中间不能直接返回导致内存释放错误 } catch(_com_error e) { printf(e.Description()); //return 0; } describe = NULL; //SendMail(EmailTo, EmailContents, server_address, port, from_email, password); } printf("执行发送完成————+++++++\n"); } } } //for (int i = 0; i < toEmailNum; i++) //{ // char ** userEmail = new char *[64]; // int userEmailNum = 0; // split(to_email[i],"-",userEmail,&userEmailNum); // if(userEmailNum = 2) // { //sprintf_s(EmailContents, "From: \"%s\"<%s>\r\n" // "To: \"%s\"<%s>\r\n" // "Subject: %s %s 通知(%s)\r\n\r\n" // "%s:\n您好!由%s(部门)%s(人员)发布的%s %s的%s,%s,变更单号为%s。" // "\n%s" // "\n请于今日内登录Teamcenter系统查阅具体变更信息!" // "\n操作路径为:打开我的工作列表->查看要执行的任务下的附件。", // ProcessOwner, from_email, userEmail[0], EmailTo, all_ID, ChangeType, ChangeTheOddNumber, userEmail[0], // group, ProcessOwner, all_ID, all_ID_name, ChangeType, ChangeTheOddNumber, all_ID,partName //); // printf("EmailTo:%s\n EmailContents:%s\n server_address:%s\n port:%d\n from_email:%s\n password:%s\n", EmailTo, EmailContents, server_address, port, from_email, password); // SendMail(userEmail[1], EmailContents, server_address, port, from_email, password); // printf("负责人:%s=======================\n", EmailContents); // printf("负责人:%=======================\n", userEmail[0]); // printf("负责人邮件地址:%s=======================\n", userEmail[1]); // //拼接负责人 // sprintf_s(assign_users, "%s%s,", assign_users, userEmail[0], ""); // } // for (int j = 0; j < userEmailNum; j++) // { // userEmail[j] = NULL; // } // userEmail = NULL; //} //qilong.lu@xmgdab.com //cout <<"aaaaaaaaaaaaaa"+valid_signoffs_count <\r\n To: \"%s\"<%s>\r\n Subject: %s %s 通知(%s)\r\n\r\n %s:\n您好!由%s(部门)%s(人员)发布的%s %s的%s于%s正式发布生效,变更单号为%s。\n请于今日内登录Teamcenter系统查阅具体变更信息!\n操作路径为:打开我的工作列表->查看要执行的任务下的附件。", // ProcessOwner, from_email, assign_user_name, EmailTo, all_ID, ChangeType, ChangeTheOddNumber, assign_user_name, group, ProcessOwner, all_ID, all_ID_name, ChangeType, date_string, ChangeTheOddNumber); // // } // printf("执行发送完成————+++++++"); // } //} DOFREE(attachments); DOFREE(ProcessOwner); DOFREE(group); DOFREE(EmailTo); DOFREE(server_address); DOFREE(from_email); DOFREE(password); DOFREE(port_string); DOFREE(ChangeType); DOFREE(ChangeTheOddNumber); //DOFREE(arguments); arg = NULL; DOFREE(temp_key); temp_val = NULL; DOFREE(date_string); for (int i = 0; i < toEmailNum; i++) { to_email[i] = NULL; } to_email = NULL; //DOFREE(valid_signoffs_tags); //10.1.100.4 //printf("节点选中的所有人=======================================%s\n", assign_users); printf("执行结束======JL_Send_Mail\n"); //SendMail(EmailTo, EmailContents, serverAddress, port, from_email, password);*/ return ifail; } ///////////////////////////////////////////////////////////////////////// char ConvertToBase64(char uc) { if (uc < 26) { return 'A' + uc; } if (uc < 52) { return 'a' + (uc - 26); } if (uc < 62) { return '0' + (uc - 52); } if (uc == 62) { return '+'; } return '/'; } // base64的实现 void EncodeBase64(char *dbuf, char *buf128, int len) { struct Base64Date6 *ddd = NULL; int i = 0; char buf[256] = { 0 }; char *tmp = NULL; char cc = '\0'; memset(buf, 0, 256); strcpy_s(buf, 256, buf128); for (i = 1; i <= len / 3; i++) { tmp = buf + (i - 1) * 3; cc = tmp[2]; tmp[2] = tmp[0]; tmp[0] = cc; ddd = (struct Base64Date6 *)tmp; dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1); dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2); dbuf[(i - 1) * 4 + 2] = ConvertToBase64((unsigned int)ddd->d3); dbuf[(i - 1) * 4 + 3] = ConvertToBase64((unsigned int)ddd->d4); } if (len % 3 == 1) { tmp = buf + (i - 1) * 3; cc = tmp[2]; tmp[2] = tmp[0]; tmp[0] = cc; ddd = (struct Base64Date6 *)tmp; dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1); dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2); dbuf[(i - 1) * 4 + 2] = '='; dbuf[(i - 1) * 4 + 3] = '='; } if (len % 3 == 2) { tmp = buf + (i - 1) * 3; cc = tmp[2]; tmp[2] = tmp[0]; tmp[0] = cc; ddd = (struct Base64Date6 *)tmp; dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1); dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2); dbuf[(i - 1) * 4 + 2] = ConvertToBase64((unsigned int)ddd->d3); dbuf[(i - 1) * 4 + 3] = '='; } return; } // 发送邮件 email:目标邮箱 body:内容 server_address:smtp地址 port:端口 from_email:发送用户邮箱 password:密码、授权码 void SendMail(char *email, char *body, char * server_address, int port, char * from_email, char * password) { int sockfd = { 0 }; char buf[1500] = { 0 }; char rbuf[1500] = { 0 }; char login[128] = { 0 }; char pass[128] = { 0 }; WSADATA WSAData; struct sockaddr_in their_addr = { 0 }; WSAStartup(MAKEWORD(2, 2), &WSAData); memset(&their_addr, 0, sizeof(their_addr)); their_addr.sin_family = AF_INET; their_addr.sin_port = htons(port); hostent* hptr = gethostbyname(server_address); memcpy(&their_addr.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length); printf("IP of %s is : %d:%d:%d:%d\n", server_address, their_addr.sin_addr.S_un.S_un_b.s_b1, their_addr.sin_addr.S_un.S_un_b.s_b2, their_addr.sin_addr.S_un.S_un_b.s_b3, their_addr.sin_addr.S_un.S_un_b.s_b4); // 连接邮件服务器,如果连接后没有响应,则2 秒后重新连接 sockfd = OpenSocket((struct sockaddr *)&their_addr); memset(rbuf, 0, 1500); while (recv(sockfd, rbuf, 1500, 0) == 0) { cout << "reconnect..." << endl; Sleep(2); sockfd = OpenSocket((struct sockaddr *)&their_addr); memset(rbuf, 0, 1500); } cout << rbuf << endl; // EHLO memset(buf, 0, 1500); sprintf_s(buf, 1500, "EHLO HYL-PC\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "EHLO REceive: " << rbuf << endl; // AUTH LOGIN memset(buf, 0, 1500); sprintf_s(buf, 1500, "AUTH LOGIN\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Auth Login Receive: " << rbuf << endl; // USER memset(buf, 0, 1500); sprintf_s(buf, 1500, from_email);//你的邮箱账号 memset(login, 0, 128); EncodeBase64(login, buf, strlen(buf)); sprintf_s(buf, 1500, "%s\r\n", login); send(sockfd, buf, strlen(buf), 0); cout << "Base64 UserName: " << buf << endl; memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "User Login Receive: " << rbuf << endl; // PASSWORD sprintf_s(buf, 1500, password);//你的邮箱密码 memset(pass, 0, 128); EncodeBase64(pass, buf, strlen(buf)); sprintf_s(buf, 1500, "%s\r\n", pass); send(sockfd, buf, strlen(buf), 0); cout << "Base64 Password: " << buf << endl; memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Send Password Receive: " << rbuf << endl; // MAIL FROM memset(buf, 0, 1500); sprintf_s(buf, 1500, "MAIL FROM: <%s>\r\n", from_email); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "set Mail From Receive: " << rbuf << endl; // RCPT TO 第一个收件人 sprintf_s(buf, 1500, "RCPT TO:<%s>\r\n", email); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Tell Sendto Receive: " << rbuf << endl; // DATA 准备开始发送邮件内容 sprintf_s(buf, 1500, "DATA\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Send Mail Prepare Receive: " << rbuf << endl; // 发送邮件内容,\r\n.\r\n内容结束标记 sprintf_s(buf, 1500, "%s\r\n.\r\n", body); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Send Mail Receive: " << rbuf << endl; // QUIT sprintf_s(buf, 1500, "QUIT\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); cout << "Quit Receive: " << rbuf << endl; //清理工作 closesocket(sockfd); WSACleanup(); return; } // 打开TCP Socket连接 int OpenSocket(struct sockaddr *addr) { int sockfd = 0; sockfd = socket(PF_INET, SOCK_STREAM, 0); if (sockfd < 0) { cout << "Open sockfd(TCP) error!" << endl; exit(-1); } if (connect(sockfd, addr, sizeof(struct sockaddr)) < 0) { cout << "Connect sockfd(TCP) error!" << endl; exit(-1); } return sockfd; }