如何写入审计追踪记录

用脚本向Audit中添加记录有两种方法,一种方法是用InserAuditEntryNew函数写入,另一种方法是生成属于“操作员输入消息”类型的报警消息,该报警消息会记录到Audit中。

Audit记录中的TargetName列是操作内容,Reason列是操作员的注释。使用InserAuditEntryNew函数生成的记录在TargetName列的内容默认为VBScripting Runtime或CScripting Runtime,而操作内容只能记录在Reason列处,这与其他记录的形式不一致,效果不好,因此在此不使用InserAuditEntryNew函数。

第二种方法,在报警记录的“系统,无确认”下的“操作员输入消息”中建立报警消息,当这条消息触发后,消息不仅会记录到报警数据库,也会记录到Audit数据库。触发报警消息可以用变量触发,也可以用脚本触发。使用脚本触发可以给消息传递参数,即向@1%s@等文本块中写入值。

WinCC中默认有一条编号为12508141的操作员输入消息,定义如下图,该消息用于记录新值旧值的更改。

12508141消息的内容不完全符合Audit消息记录的需要,新建一条编号为12508142消息。项目中可能会用WinCC控制多台设备,定义文本块@10%s@的作用是记录该操作针对哪台设备,文本块@7%s@记录执行了什么操作。有些项目中不使用Audit trail组件,而是用报警记录的数据库记录审计追踪,因此可在错误点列填上@10%s@,使用报警控件查看时便于筛选。该消息定义如下:

使用C脚本生成操作员消息

WinCC支持C和VB两种脚本,C脚本中提供了GCreateMyOperationMsg()函数生成操作员消息。

函数原型:

int GCreateMyOperationMsg( DWORD dwFlags, DWORD dwMsgNum, char* lpszPictureName, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)

参数:

  • dwFlags,该参数指定如何生成注释,可用以下常量值,值可以用或运算“|”输入:

常数

描述

FLAG_COMMENT_PARAMETER

0x00000001

文本在运行时直接作为消息输入,没有自己的注释对话框。对注释的指针不能等于“NULL”。

FLAG_COMMENT_DIALOG

0x00000003

出现一个注释对话框,输入的注释被转移到消息中

FLAG_TEXTID_PARAMETER

0x00000100

提供文本库中的一个文本ID,将文本插入到消息的过程值中。

  • dwMsgNum,该参数为消息编号,触发该编号的消息。消息必须属于“操作员输入消息”类型,不可使用其他类型的消息。
  • lpszPictureName,该参数未在函数中使用,不起任何作用。
  • lpszObjectName,该参数会写入到文本块@1%s@中和szInstance属性中,szInstance属性等同于文本块@10%s@。
  • dwMyTextID,该参数是文本库ID,值会被写入到值@8%g@中。如果dwFlags参数为FLAG_TEXTID_PARAMETER,会将文本库中该ID的文本写入到文本块@8%s@中。
  • doValueOld,该参数是变量旧值,值会被写入到值@2%g@中,在audit中会写入到OldValue列中。
  • doValueNew,该参数是变量新值,值会被写入到值@3%g@中,在audit中会写入到NewValue列中。
  • pszComment,该参数是注释字符串,如果dwFlags参数为FLAG_COMMENT_PARAMETER,该字符串会写入到报警的注释中,写入到Audit的Reason列。

返回值:

描述

0

函数执行完成没有任何错误

-101

消息不能被编辑

-201

当调用"MSRTGetComment()"特征引发一个错误

-301

当调用"MSRTCreateMsgInstanceWithComment()"特征引发一个错误

GCreateMyOperationMsg()函数生成的消息文本中未使用文本块@7%s@,我们参考GCreateMyOperationMsg函数进行修改,重新创建一个操作员消息函数GCreateMyOperationMsg2(),该函数值用lpszMsg参数代替lpszPictureName参数,lpszMsg参数的值被写入文本块@7%s@中。GCreateMyOperationMsg2()函数配合12508142消息使用。

函数原型:

int GCreateMyOperationMsg2( DWORD dwFlags, DWORD dwMsgNum, char* lpszMsg, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)

参数:

  • lpszMsg,该参数记录操作消息,会写入文本块@7%s@中。
  • 其他参数与GCreateMyOperationMsg()函数一致。

函数代码:

  1. #pragma code ("kernel32.dll")
  2. void GetLocalTime( LPSYSTEMTIME lpSystemTime);
  3. BOOL GetComputerNameA(LPSTR Computername, LPDWORD size);
  4. VOID Sleep(DWORD dwMilliseconds); //RQ:1072746
  5.  
  6. #pragma code()
  7.  
  8. #define FLAG_COMMENT_PARAMETER 0x00000001
  9. #define FLAG_COMMENT_DIALOG 0x00000003
  10.  
  11. #define FLAG_TEXTID_PARAMETER 0x00000100
  12.  
  13. int GCreateMyOperationMsg2( DWORD dwFlags, DWORD dwMsgNum, char* lpszMsg, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment )
  14. {
  15.  
  16. MSG_RTDATA_INSTANCECOMMENT_STRUCT MsgCreateEx;
  17. MSG_RTDATA_STRUCT MsgRTData; // for comment dialog
  18. CMN_ERROR scError;
  19. int iRet= FALSE;
  20. DWORD dwServiceID = 0;
  21. BOOL bOK;
  22. SYSTEMTIME time;
  23. DWORD dwBufSize = 256;
  24.  
  25. char szComputerName[256] = "";
  26. char szSource[256] = "";
  27. char szMyText[MSG_MAX_TB_CONTENT + 1] = "";
  28. char szTmp[256] = ""; // for diagnosis output
  29. char* pszPrefix; // to define the type of WinCC project
  30. char* lpszCurrentUser;
  31. char* lpszParent;
  32.  
  33. char * pszServerPrefix;
  34.  
  35. //RQ:1072746 begin
  36. DWORD dwMaxCheckTime = 5000; // max time to wait 5000ms=5sec.
  37. DWORD dwStepCheckTime = 500; // start stepping waittime with 500ms
  38. DWORD dwReduceStepTime = 100; // reduce the steptime here by 100ms
  39. DWORD dwActWaitedTime = 0;
  40. DWORD dwInx = 0;
  41. //RQ:1072746 end
  42.  
  43. printf("Start GCreateMyOperationMsg \r\n");
  44.  
  45. //======================================
  46. // INIT_MESSAGE_STRUCT
  47. //======================================
  48. memset(&MsgCreateEx,0,sizeof(MsgCreateEx));
  49. memset(&MsgRTData,0,sizeof(MsgRTData));
  50. memset(&scError,0,sizeof(scError));
  51.  
  52. GetLocalTime(&time);
  53. MsgCreateEx.stMsgTime = time;
  54. MsgRTData.stMsgTime = time;
  55.  
  56. MsgCreateEx.dwMsgNr = dwMsgNum;
  57. MsgRTData.dwMsgNr = dwMsgNum;
  58.  
  59. MsgCreateEx.wPValueUsed = (WORD)(0x0000 ); // no real process value used
  60. MsgRTData.wPValueUsed = (WORD)(0x0000 );
  61. MsgCreateEx.wTextValueUsed = 0x001F; // text values 1 .. 5 used for textblocks 1 .. 5
  62. MsgRTData.wTextValueUsed = 0x001F; // text values 1 .. 5 used for textblocks 1 .. 5
  63. MsgCreateEx.dwFlags = MSG_FLAG_TEXTVALUES;
  64. MsgRTData.dwFlags = MSG_FLAG_COMMENT | MSG_FLAG_TEXTVALUES;
  65.  
  66. MsgCreateEx.dwMsgState = MSG_STATE_COME;
  67. MsgRTData.dwMsgState = MSG_STATE_COME;
  68.  
  69. GetComputerNameA(szComputerName, &dwBufSize);
  70. sprintf(szTmp, "Computername = %s \r\n", szComputerName);
  71. printf(szTmp);
  72. strncpy(MsgCreateEx.szComputerName, szComputerName, sizeof(MsgCreateEx.szComputerName) -1);
  73.  
  74. lpszCurrentUser = GetTagChar("@NOP::@CurrentUser");
  75. if (NULL != lpszCurrentUser )
  76. {
  77. strncpy( MsgCreateEx.szUser, lpszCurrentUser, sizeof (MsgCreateEx.szUser) - 1);
  78. }
  79.  
  80. if ( dwFlags & FLAG_TEXTID_PARAMETER)
  81. {
  82. MsgCreateEx.dPValue[7] = dwMyTextID; // TextID
  83. MsgCreateEx.wPValueUsed = 0x0080; // for process value 8
  84. }
  85.  
  86. MsgCreateEx.wPValueUsed = (WORD)(MsgCreateEx.wPValueUsed | 0x0006);
  87. MsgCreateEx.dPValue[1] = doValueOld; // old value
  88. MsgCreateEx.dPValue[2] = doValueNew; // new value
  89.  
  90. //======================================
  91. // START_MESSAGE_SERVICE
  92. //======================================
  93. memset(&scError,0,sizeof(scError));
  94.  
  95. // GetServerPrefix to determine MC or Server
  96. GetServerTagPrefix(&pszServerPrefix, NULL, NULL); //Return-Type: void
  97. if (NULL == pszServerPrefix)
  98. {
  99. printf("Serverapplication or Single Client\r\n");
  100. bOK = MSRTStartMsgService( &dwServiceID, NULL, NULL, 0, NULL, &scError ); // activate service
  101. }
  102. else
  103. {
  104. printf("MultiClient with Prefix : %s\r\n",pszServerPrefix); //Return - Type :char*
  105. bOK = MSRTStartMsgServiceMC( &dwServiceID, NULL, NULL, 0, NULL,pszServerPrefix, &scError ); // activate service
  106. }
  107.  
  108. if (bOK == FALSE)
  109. {
  110. printf("GCreateMyOperationMsg() - Unable to start message service! \r\n");
  111. sprintf(szTmp, " Error1 = 0x%0x, Errortext = %s \r\n", scError.dwError1, scError.szErrorText);
  112. printf(szTmp);
  113.  
  114. return (-101);
  115. }
  116. //======================================
  117.  
  118. //======================================
  119. // PARSE PARAMETERS
  120. //======================================
  121. if ( ( dwFlags & FLAG_COMMENT_PARAMETER ) && ( NULL != pszComment ) )
  122. {
  123. strncpy(MsgCreateEx.szComment, pszComment, sizeof (MsgCreateEx.szComment) - 1);
  124. MsgCreateEx.dwFlags |= MSG_FLAG_COMMENT;
  125. }
  126.  
  127. if ( dwFlags & FLAG_COMMENT_DIALOG )
  128. MsgCreateEx.dwFlags |= MSG_FLAG_COMMENT;
  129.  
  130. if (lpszObjectName!= NULL) // = tagname
  131. {
  132. strncpy (szSource, lpszObjectName, sizeof (lpszObjectName) - 1);
  133. strncpy ( MsgCreateEx.szInstance, lpszObjectName, sizeof (MsgCreateEx.szInstance) - 1);
  134. strncpy ( MsgCreateEx.mtTextValue[0].szText, lpszObjectName, sizeof (MsgCreateEx.mtTextValue[1].szText) - 1);
  135. }
  136.  
  137. if ( szMyText != NULL)
  138. {
  139. strncpy ( MsgCreateEx.mtTextValue[1].szText, szMyText , sizeof (MsgCreateEx.mtTextValue[1].szText) - 1);
  140. }
  141.  
  142. if ( lpszMsg != NULL)
  143. {
  144. strncpy ( MsgCreateEx.mtTextValue[6].szText, lpszMsg , sizeof (MsgCreateEx.mtTextValue[6].szText) - 1);
  145. }
  146. //======================================
  147.  
  148. //======================================
  149. // CREATE MESSAGE
  150. //======================================
  151. bOK = MSRTCreateMsgInstanceWithComment(dwServiceID, &MsgCreateEx, &scError) ;
  152. if ( TRUE == bOK)
  153. {
  154. if (FLAG_COMMENT_DIALOG == (dwFlags & FLAG_COMMENT_DIALOG) )
  155. {
  156. BOOL bOkay;
  157. HWND hWnd = FindWindow("PDLRTisAliveAndWaitsForYou", NULL);
  158.  
  159. //RQ:1072746 begin
  160. MSG_COMMENT_STRUCT mComment;
  161. sprintf( mComment.szUser, MsgCreateEx.szUser, sizeof(mComment.szUser) - 1 );
  162.  
  163. for (dwInx = 1;
  164. dwActWaitedTime < dwMaxCheckTime;
  165. dwInx++)
  166. {
  167. memset(&scError,0,sizeof(scError));
  168. mComment.dwMsgNr = dwMsgNum;
  169. mComment.stTime = time;
  170. bOkay = MSRTGetComment (dwServiceID, &mComment, &scError);
  171. if (TRUE == bOkay)
  172. {
  173. break;
  174. }
  175. else
  176. {
  177. Sleep(dwStepCheckTime);
  178. printf("#W401: GCreateMyOperationMsg(): pre MSRTGetComment() performance warning: waited=%ld / step=%ld/ round=%ld\r\n", dwActWaitedTime+dwStepCheckTime, dwStepCheckTime, dwInx);
  179. }
  180. dwActWaitedTime += dwStepCheckTime;
  181. if (100 < dwStepCheckTime)
  182. {
  183. dwStepCheckTime -=dwReduceStepTime;
  184. }
  185. }
  186. //RQ:1072746
  187.  
  188. memset(&scError,0,sizeof(scError));
  189. bOkay= MSRTDialogComment (hWnd, &MsgRTData, &scError);
  190. if (TRUE == bOkay)
  191. {
  192. //MSG_COMMENT_STRUCT mComment; //RQ:1072746
  193. mComment.dwMsgNr = dwMsgNum;
  194. mComment.stTime = time;
  195. sprintf( mComment.szUser, MsgCreateEx.szUser, sizeof(mComment.szUser) - 1 );
  196.  
  197. memset(&scError,0,sizeof(scError));
  198. bOkay = MSRTGetComment (dwServiceID, &mComment, &scError);
  199. if (TRUE == bOkay)
  200. {
  201. strncpy(MsgCreateEx.szComment, mComment.szText, sizeof (MsgCreateEx.szComment) - 1);
  202. }
  203. }
  204. else
  205. {
  206. printf("#E201: GCreateMyOperationMsg() - Error at MSRTGetComment() szErrorText=\"%s\" error2=%d\r\n", scError.szErrorText, scError.dwError2);
  207. iRet = -201;
  208. }
  209. }
  210.  
  211. }
  212.  
  213. if(bOK == FALSE)
  214. {
  215. printf ("#E301: GCreateMyOperationMsg() - Error at MSRTCreateMsgInstanceWithComment() szErrorText=\"%s\"\r\n", scError.szErrorText);
  216. iRet = -301;
  217. }
  218. //======================================
  219.  
  220. //======================================
  221. // STOP_MESSAGE_SERVICE
  222. //======================================
  223. bOK= MSRTStopMsgService( dwServiceID, &scError);
  224. printf("End GCreateMyOperationMsg \r\n");
  225. return (iRet);
  226. }

C脚本操作员消息函数二次封装

在不要电子签名只需记录操作消息的地方,为了更方便使用,对函数进行二次封装为函数CreateMyOpMsg()。

函数原型:

int CreateMyOpMsg(char* lpszMsg, char* lpszdevice)

参数:

  • lpszMsg,该参数记录操作消息,写入文本块@7%s@中。
  • lpszdevice,该参数为设备名,写入到文本块@10%s@中。

返回值:

描述

0

函数执行完成没有任何错误

-101

消息不能被编辑

-201

当调用"MSRTGetComment()"特征引发一个错误

-301

当调用"MSRTCreateMsgInstanceWithComment()"特征引发一个错误

函数代码:

  1. #include "apdefap.h"
  2.  
  3. int CreateMyOpMsg(char* lpszMsg, char* lpszdevice
  4. {
  5. char userComm[1024]="";
  6. return GCreateMyOperationMsg2(0x00000001 ,12508142 , lpszMsg, lpszdevice, 0, 0 , 0 , userComm); //Return-Type: long int
  7. }

  

用VB脚本生成操作员消息

使用VB脚本创建操作员消息的脚本如下:

  1. '创建操作员消息
  2. dim myAlarm
  3. Set myAlarm = HMIRuntime.Alarms(12508142)
  4. MyAlarm.State = 5
  5. '--------------------------
  6. 'State Alarm Log Status
  7. '1 Came In
  8. '2 Went Out
  9. '5 Came in and comment
  10. '6 Gone and comment
  11. '--------------------------
  12. myAlarm.Comment = userComment
  13. myAlarm.UserName = userName
  14. myAlarm.ProcessValues(10) = Device
  15. myAlarm.ProcessValues(7) = Msg
  16. MyAlarm.Create

注意:使用VBS生成的操作员消息,在报警记录中没有计算机名。

VB脚本操作员消息函数二次封装

在不要电子签名只需记录操作消息的地方,为了更方便使用,对函数进行二次封装为函数CreateMyOpMsg()。

函数原型:

Function CreateMyOpMsg(inputMsg, device)

参数:

  • inputMsg,该参数记录操作消息,写入文本块@7%s@中。
  • device,该参数为设备名,写入到文本块@10%s@中。

返回值:


函数代码:

  1. Function CreateMyOpMsg(inputMsg, device)
  2. '创建操作员消息
  3. dim myAlarm
  4. Set myAlarm = HMIRuntime.Alarms(12508142)
  5. MyAlarm.State = 5
  6. '--------------------------
  7. 'State Alarm Log Status
  8. '1 Came In
  9. '2 Went Out
  10. '5 Came in and comment
  11. '6 Gone and comment
  12. '--------------------------
  13. myAlarm.Comment = userComment
  14. myAlarm.UserName = userName
  15. myAlarm.ProcessValues(10) = Device
  16. myAlarm.ProcessValues(7) = inputMsg
  17. MyAlarm.Create
  18. End Function

  

如何生成电子签名

C脚本执行电子签名

函数原型:

int EsigDialog(const char * inputMsg, const char * device)

参数:

  • inputMsg,该参数为执行该操作的描述字符串,写入到文本块@7%s@中。
  • device,该参数为设备名,写入到文本块@10%s@中。

返回值:

描述
-1 函数执行遇到错误
1 电子签名通过
2 用户取消了电子签名
3 三次电子签名未通过

注意:

该函数依赖函数GCreateMyOperationMsg2()

函数代码:

  1. #include "apdefap.h"
  2.  
  3. int EsigDialog(const char * inputMsg, const char * device)
  4. {
  5. //获取用户名和计算机名
  6. char *userName = GetTagChar("@NOP::@CurrentUser"); //Return-Type: char*
  7. char *displayedUser = GetTagChar("@NOP::@CurrentUserName"); //Return-Type: char*
  8. char *computerName = GetTagChar("@NOP::@LocalMachineName"); //Return-Type: char*
  9. char *Domain = ""; //如果加入了域,在此填写域名
  10. int nRet = 0;
  11. char szBuf[1024]="";
  12. char myComm[1024]="";
  13. char userComm[1024]="";
  14. VARIANT vtComment;
  15. __object* EsigDlg;
  16.  
  17. /*---判断用户是否登录---*/
  18. if (strlen(userName) == 0) {
  19. MessageBox(NULL,"用户未登录,请登录后再执行!","Error",MB_SYSTEMMODAL|MB_OK);
  20. return -1;
  21. }
  22.  
  23. /*---电子签名---*/
  24. EsigDlg = __object_create("CCESigDlg.ESIG");
  25.  
  26. if (!EsigDlg) {
  27. printf("Failed to create Picture Object\n");
  28. return -1;
  29. }
  30.  
  31. EsigDlg->forcecomment = FALSE; //非强制注释
  32. nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment);
  33. __object_delete(EsigDlg);
  34. /*---提取注释---*/
  35. sprintf(userComm,"%ls",vtComment.u.bstrVal);
  36. VariantClear(&vtComment);
  37. /*---合并注释---*/
  38. /*
  39. if (strlen(inputMsg)>0 && strlen(userComm)>0) {
  40. sprintf(myComm,"%s:%s", inputMsg, userComm);
  41. }
  42. else if (strlen(inputMsg)>0) {
  43. sprintf(myComm,"%s", inputMsg);
  44. }
  45. else if (strlen(userComm)>0) {
  46. sprintf(myComm,"%s", userComm);
  47. }
  48. */
  49.  
  50. switch(nRet)
  51. {
  52. case 1:
  53. //InsertAuditEntryNew("","",myComm,0,szBuf);
  54. GCreateMyOperationMsg2(0x00000001, 12508142, inputMsg, device, 0, 0, 0, userComm); //Return-Type: long int
  55. break;
  56. case 2:
  57. break;
  58. case 3:
  59. break;
  60. }
  61.  
  62. return nRet;
  63. }

  

C脚本执行电子签名并写入变量新值:

 函数原型:

int TagNewValueES(const char *winccTagName,double newValue, const char *description, const char *device)

参数:

  • winccTagName,该参数为WinCC变量名,与参数description拼接后写入到文本块@7%s@中。
  • newValue,该参数为要写入的新值,只能为数值,不支持字符串,写入到数值块@3%g@中。
  • description,该参数为变量描述,说明该变量的含义,与参数winccTagName拼接后写入到文本块@7%s@中。
  • device,该参数为设备名,写入到文本块@10%s@中。

返回值:

描述
-1 函数执行遇到错误
1 电子签名通过
2 用户取消了电子签名
3 三次电子签名未通过

注意:

该函数依赖函数GCreateMyOperationMsg2()

函数代码:

  1. #include "apdefap.h"
  2.  
  3. int TagNewValueES(const char *winccTagName,double newValue, const char *description, const char *device)
  4. {
  5. //获取用户名和计算机名
  6. char *userName = GetTagChar("@NOP::@CurrentUser"); //Return-Type: char*
  7. char *displayedUser = GetTagChar("@NOP::@CurrentUserName"); //Return-Type: char*
  8. char *computerName = GetTagChar("@NOP::@LocalMachineName"); //Return-Type: char*
  9. char *Domain = "" //如果加入了域,在此填写域名
  10. int nRet = 0;
  11. char szBuf[1024]="";
  12. char myComm[1024]="";
  13. char userComm[1024]="";
  14. char tagDescription[1024]="";
  15. double oldValue;
  16. VARIANT vtComment;
  17. __object* EsigDlg;
  18.  
  19. /*---判断用户是否登录---*/
  20. if (strlen(userName) == 0) {
  21. MessageBox(NULL,"用户未登陆,请登陆后再执行!","Error",MB_SYSTEMMODAL|MB_OK);
  22. return -1;
  23. }
  24.  
  25. /*---电子签名---*/
  26. EsigDlg = __object_create("CCESigDlg.ESIG");
  27.  
  28. if (!EsigDlg) {
  29. printf("Failed to create Picture Object\n");
  30. return -1;
  31. }
  32.  
  33. EsigDlg->forcecomment = FALSE; //非强制注释
  34. nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment);
  35. __object_delete(EsigDlg);
  36. /*---提取注释---*/
  37. sprintf(userComm,"%ls",vtComment.u.bstrVal);
  38. VariantClear(&vtComment);
  39. /*---合并注释---*/
  40. /*
  41. if (strlen(description)>0 && strlen(userComm)>0) {
  42. sprintf(myComm,"%s:%s", description, userComm);
  43. }
  44. else if (strlen(description)>0) {
  45. sprintf(myComm,"%s", description);
  46. }
  47. else if (strlen(userComm)>0) {
  48. sprintf(myComm,"%s", userComm);
  49. }
  50. */
  51.  
  52. switch(nRet)
  53. {
  54. case 1:
  55. //获取旧值
  56. //strcpy(oldValue,GetTagChar(winccTagName));
  57. oldValue = GetTagDouble(winccTagName); //Return-Type: double
  58. //写入新值
  59. //SetTagChar(winccTagName,newValue);
  60. SetTagDouble(winccTagName,newValue); //Return-Type: BOOL
  61. //创建操作员消息
  62. //InsertAuditEntryNew(oldValue,newValue,myComm,0,szBuf);
  63. sprintf(tagDescription,"%s %s", winccTagName, description);
  64. GCreateMyOperationMsg2(0x00000001 ,12508141 , tagDescription, device, 0, oldValue , newValue , userComm); //Return-Type: long int
  65.  
  66. break;
  67. case 2:
  68. break;
  69. case 3:
  70. break;
  71. }
  72.  
  73. return nRet;
  74.  
  75. }

  

VB脚本执行电子签名

函数原型:

Function EsigDialog(inputMsg, device)

参数:

  • inputMsg,该参数为执行该操作的描述字符串,写入到文本块@7%s@中。
  • device,该参数为设备名,写入到文本块@10%s@中。

返回值:

描述
-1 函数执行遇到错误
1 电子签名通过
2 用户取消了电子签名
3 三次电子签名未通过

函数代码:

  1. Function EsigDialog(inputMsg, device)
  2. '获取用户名和计算机名
  3. Dim userName, displayedUser, Domain, computerName
  4. userName = HMIRuntime.Tags("@NOP::@CurrentUser").Read
  5. displayedUser = HMIRuntime.Tags("@NOP::@CurrentUserName").Read
  6. computerName = HMIRuntime.Tags("@NOP::@LocalMachineName").Read
  7. Domain = ""
  8. If userName = "" Then
  9. Msgbox "用户未登陆,请登陆后再执行"
  10. EsigDialog = -1
  11. Exit Function
  12. End If
  13.  
  14. '电子签名
  15. Dim myEsig
  16. Dim myComment
  17. Dim userComment
  18. Dim ret
  19. Set myEsig = CreateObject("CCEsigDlg.ESIG")
  20. '不强制注释
  21. myEsig.forcecomment = False
  22. ret = myEsig.showDialog(userName,displayedUser,Domain, HMIRuntime.Language, userComment)
  23. ' If Trim(inputMsg)<>"" And Trim(userComment)<>"" Then
  24. ' myComment = inputMsg&":"&userComment
  25. ' Elseif Trim(inputMsg)<>"" Then
  26. ' myComment = inputMsg
  27. ' Elseif Trim(userComment)<>"" Then
  28. ' myComment = userComment
  29. ' Else
  30. ' myComment = ""
  31. ' End If
  32.  
  33. Select Case ret
  34. Case 1 '用户成功获得验证
  35. 'Call InsertAuditEntryNew("", "", myComment, 0)
  36. '创建操作员消息
  37. dim myAlarm
  38. Set myAlarm = HMIRuntime.Alarms(12508142)
  39. MyAlarm.State = 5
  40. '--------------------------
  41. 'State Alarm Log Status
  42. '1 Came In
  43. '2 Went Out
  44. '5 Came in and comment
  45. '6 Gone and comment
  46. '--------------------------
  47. myAlarm.Comment = userComment
  48. myAlarm.UserName = userName
  49. myAlarm.ProcessValues(10) = device
  50. myAlarm.ProcessValues(7) = inputMsg
  51. MyAlarm.Create
  52. Case 2 '用户使用“取消”按钮关闭了对话框。
  53.  
  54. Case 3 '用户 3 次验证均失败。
  55.  
  56. End Select
  57.  
  58. EsigDialog = ret
  59. End Function

  

VB脚本执行电子签名并写入新值

函数原型:

Function TagNewValueES(WinccTagName,NewValue,description,device)

参数:

  • winccTagName,该参数为WinCC变量名,与参数description拼接后写入到文本块@7%s@中。
  • newValue,该参数为要写入的新值,只能为数值,不支持字符串,写入到数值块@3%g@中。
  • description,该参数为变量描述,说明该变量的含义,与参数winccTagName拼接后写入到文本块@7%s@中。
  • device,该参数为设备名,写入到文本块@10%s@中。

返回值:

描述
-1 函数执行遇到错误
1 电子签名通过
2 用户取消了电子签名
3 三次电子签名未通过

函数代码:

  1. Function TagNewValueES(WinccTagName,NewValue,description,device)
  2. '获取用户名和计算机名
  3. Dim userName, displayedUser, Domain, computerName
  4. userName = HMIRuntime.Tags("@NOP::@CurrentUser").Read
  5. displayedUser = HMIRuntime.Tags("@NOP::@CurrentUserName").Read
  6. computerName = HMIRuntime.Tags("@NOP::@LocalMachineName").Read
  7. Domain = ""
  8. If userName = "" Then
  9. Msgbox "用户未登陆,请登陆后再执行"
  10. TagNewValueES = -1
  11. Exit function
  12. End If
  13.  
  14. '电子签名
  15. Dim myEsig
  16. Dim myComment
  17. Dim userComment
  18. Dim ret
  19. Set myEsig = CreateObject("CCEsigDlg.ESIG")
  20. '不强制注释
  21. myEsig.forcecomment = False
  22. ret = myEsig.showDialog(userName,displayedUser, Domain, HMIRuntime.Language, userComment)
  23. ' If Trim(description)<>"" And Trim(userComment)<>"" Then
  24. ' myComment = description&":"&userComment
  25. ' Elseif Trim(description)<>"" Then
  26. ' myComment = description
  27. ' Elseif Trim(userComment)<>"" Then
  28. ' myComment = userComment
  29. ' Else
  30. ' myComment = ""
  31. ' End If
  32.  
  33. Select Case ret
  34. Case 1 '用户成功获得验证
  35. '获取变量旧值
  36. dim OldValue, WinCCTag
  37. Set WinCCTag = HMIRuntime.Tags(WinccTagName)
  38. OldValue = WinCCTag.read
  39. '给变量写入新值
  40. WinCCTag.Write NewValue
  41. If WinCCTag.LastError <> 0 Then
  42. Msgbox WinCCTag.ErrorDescription
  43. TagNewValueES = -1
  44. Exit Function
  45. End If
  46. '创建操作员消息
  47. dim myAlarm
  48. set myAlarm = HMIRuntime.Alarms(12508141) '@10%s@: @7%s@ @102%s@ 新=@3%g@ @8%s@ 旧=@2%g@ @8%s@'
  49. MyAlarm.State = 5
  50. '--------------------------
  51. 'State Alarm Log Status
  52. '1 Came In
  53. '2 Went Out
  54. '5 Came in and comment
  55. '6 Gone and comment
  56. '--------------------------
  57. myAlarm.Comment = userComment
  58. myAlarm.UserName = userName
  59. myAlarm.ProcessValues(2) = OldValue'旧值
  60. myAlarm.ProcessValues(3) = NewValue'新值
  61. myAlarm.ProcessValues(7) = WinccTagName &" "&description '变量名+变量描述
  62. myAlarm.ProcessValues(10) = device'设备名
  63. MyAlarm.Create
  64.  
  65. 'InsertAuditEntryNew(OldValue, NewValue, myComment, 0)
  66.  
  67. Case 2 '用户使用“取消”按钮关闭了对话框。
  68.  
  69. Case 3 '用户 3 次验证均失败。
  70.  
  71. End Select
  72. TagNewValueES = ret
  73. End Function

  

WinCC的电子签名与审计追踪的更多相关文章

  1. Firebird 审计追踪

    Firebird 打开审计追踪功能,即在服务器上打开日志记录功能,根据配置记录不同类型的服务器执行情况. 1.首先修改Firebird.conf文件,打开审计功能: AuditTraceConfigF ...

  2. ABP文档 - 审计日志

    文档目录 本节内容: 简介 关于 IAuditingStore 配置 通过特性启用/禁用 注意 简介 维基百科:“一个审计追踪(也叫审计日志)是一个安全相关的时序记录.记录组.和/或记录源和目标,作为 ...

  3. ABP官方文档翻译 4.6 审计日志

    审计日志 介绍 关于IAuditingStore 配置 通过特性启用/禁用 注意事项 介绍 维基百科:“审计追踪(也称为审计日志)是与安全相关的按时间先后的记录.记录集合.记录的目的地和源,提供一系列 ...

  4. 数据库开启对sys用户的审计

    需求:客户想对数据库开启sys用户的审计功能,关闭其它用户的审计功能. 1)再一次巡检报告中,我们发现数据库版本11.2.0.4,开启审计功能,提供的建议如下,关闭审计alter system set ...

  5. Event Sourcing Pattern 事件源模式

    Use an append-only store to record the full series of events that describe actions taken on data in ...

  6. Testing - 测试基础 - 阶段

    估算 测试对软件工作量的估算的准确性 测试评估软件系统的状况的准确性 关注点: 不准确的估算 不适当的开发过程 不真实的状态报告 如何知道对工作量的估算是正确的 估算工作量的工具很容易出错 对软件工作 ...

  7. SharePoint Server 2010 中的基本任务

    SharePoint Foundation 和 SharePoint Server 概述 SharePoint Foundation 2010 是一项用于 SharePoint 网站的基础技术,它可以 ...

  8. Threat Risk Modeling Learning

    相关学习资料 http://msdn.microsoft.com/en-us/library/aa302419(d=printer).aspx http://msdn.microsoft.com/li ...

  9. 每个极客都应该知道的Linux技巧

    每个极客都应该知道的Linux技巧 2014/03/07 | 分类: IT技术 | 0 条评论 | 标签: LINUX 分享到:18 本文由 伯乐在线 - 欣仔 翻译自 TuxRadar Linux. ...

随机推荐

  1. cookie、session、token的区别

    一.  cookie 1.什么是cookie? Cookie 技术产生源于 HTTP 协议在互联网上的急速发展.随着互联网时代的策马奔腾,带宽等限制不存在了,人们需要更复杂的互联网交互活动,就必须同服 ...

  2. synchronized被这么问,谁能受得了

    synchronized是面试中经常会被问到的知识点,相关的问题点也很多,问题答案涉及的知识点也很多,有经验的面试官就会顺着你的答案不断追问一下,下面的对话场景就是相关面试题的连环炮. 面试官:说一下 ...

  3. Python-TCP客户端程序开发

    TCP客户端,需要与服务端建立连接,连接建立成功后才可以进行数据的传输. # 1.导入模块 import socket if __name__ == '__main__': # 2.创建套接字对象 t ...

  4. UITableView 相关方法

    最近闲来无事,总结一下 UITableViewDataSource和 UITableViewDelegate方法 UITableViewDataSource @required - (NSIntege ...

  5. UIView的作用

    UIView [UIView的作用] 主要用来显示应用程序的内容,可以作为label.button等控件的容器.表示屏幕上的一块矩形区域,同时可以处理该区域的绘制和触屏事件. MVC,MVVM等设计架 ...

  6. Node升级——Node Binary管理模块"n"

    Node.js的开发非常活跃,它的最新稳定版本也频繁变化,你不时会发现,一个模块不能在你当前的Node版本上使用,此时你需要升级Node 幸运的是,可以用一种非常简单的方法来管理你的Node版本,即使 ...

  7. 为什么每一个爬虫工程师都应该学习 Kafka

    这篇文章不会涉及到Kafka 的具体操作,而是告诉你 Kafka 是什么,以及它能在爬虫开发中扮演什么重要角色. 一个简单的需求 假设我们需要写一个微博爬虫,老板给的需求如下: 开发爬虫对你来说非常简 ...

  8. [TimLinux] JavaScript table的td内容超过宽度缩为三个点

    1. 思路 CSS控制td内容自动缩为三个点 JS控制鼠标悬浮显示td全部内容 2. 实现 HTML代码: <!DOCTYPE html> <html> <head> ...

  9. JavaScript 逻辑与(&&) 与 逻辑或(||) 运算规则

    逻辑与(&&) 逻辑与(&&)操作可以应用于任何的操作类型,不仅仅是布尔值, 在有一个操作数不是布尔值的情况下,&&操作符就不一定返回布尔值:遵循下面规 ...

  10. JMeter之SteppingShape

    1.背景 其实是这样的,最近包括以前都有同事问过宝路一个问题:JMeter测试计划中涉及到梯度压测时,整个测试计划执行完毕,聚合报告看的是整体的结果啊!并不能直观看到每个梯度下的吞吐量的值(虽然可以通 ...