Thinkai's Blog

Autohoutkey|Python|php|aardio|VOIP|IT 爱好者

正在浏览分类 IT

总共找到 154 篇

在ado中使用ODBC的dsn连接Oracle、Mysql等数据库 Autohotkey 1496

作者为 发表

Autohotkey

ODBC驱动可以搜索“数据库类型 windows ODBC 插件”安装;DSN需要在开始菜单,Windows管理工具中找“ODBC 数据源(32 位)”,此处如果用32位的AHK则用32位的版本添加,不然无法访问。

a := new adodb
a.open("DSN=testdb;UID=thinkai;PWD=password;") ;到DSN里面配置了用户名密码则UID PWD不用配置。
ret := a.GetTable("select getdate()")
MsgBox % ret.1.1

class adodb
{
	;static conn

	__New() ;新建
	{
	this.conn:= ComObjCreate("ADODB.connection") ;初始化COM
	}

	open(connect_str) ;打开文件
	{
		try
			this.conn.Open(connect_str)
		catch e
			return e.Message
	}

	close() ;关闭文件
	{
		this.conn.Close()
	}

	GetTable(sql)
	{
		t := []
		query := this.conn.Execute(sql)
		if RegExMatch(sql,"i)^select*")
		{
			try
			{
				fetchedArray := query.GetRows() ;取出数据(二维数组)
				colSize := fetchedArray.MaxIndex(1) + 1 ;列最大值 tips:从0开始 所以要+1
				rowSize := fetchedArray.MaxIndex(2) + 1 ;行最大值 tips:从0开始 所以要+1
				loop, % rowSize
				{
					i := (y := A_index) - 1
					t[y] := []
					loop, % colSize
					{
						j := (x := A_index) - 1
						t[y][x] := fetchedArray[j,i] ;取出二维数组内值
					}
				}
			}
			query.Close()
			return t
		}
	}
}


Class_MySQLAPI.ahk及简单测试 Autohotkey 457

作者为 发表

Autohotkey

#Include Class_MySQLAPI.ahk
#NoEnv
My_DB := New MySQLAPI         
My_DB.Real_Connect("127.0.0.1", "root", "pass","db1")    ;主机,用户名,密码,数据库               
SQL := "SELECT now() as nowtime,1 as Status" ;语句
Result := My_DB.Query(SQL) ;查询
MsgBox % var_dump(My_DB.GetResult()) ;获取数组结果

var_dump(obj,level:=0){
    static id,str
	id++
    if id=1
        str := ""
    if IsObject(obj)
    {
        space =
        loop % level
            space .= A_Tab
        str .= space "{`n"
        for k,v in obj
        {
            if IsObject(v)
            {
                str .= space A_Tab (RegExMatch(k,"^\d+$") ? k : """" k """") ":`n"
                var_dump(v,level+1)
                str := RegExReplace(str,"(*ANYCRLF)\n$",",`n")
            }
            else
                str .= space A_Tab (RegExMatch(k,"^\d+$") ? k : """" k """") ":""" RegExReplace(v,"""","""""") """,`n"
        }
        str := RegExReplace(str,"(*ANYCRLF),\n*$","`n")
        str .= space "}`n"
    }
    else
        str := obj
    if !level
		id := 0
	return str
}


Class_MySQLAPI.ahk(需要libmysql.dll):

; ======================================================================================================================
; Wrapper class for MySQL C API functions        -> http://dev.mysql.com/doc/refman/5.5/en/c-api-functions.html
; Based on "MySQL Library functions" by panofish -> http://www.autohotkey.com/board/topic/72629-mysql-library-functions
; Namespace:   MySQLAPI
; AHK version: 1.1.10+
; Author:      panofish/just me
; Version:     1.0.01.00/2015-08-20/just me        - libmysql.dll error handling
;              1.0.00.00/2013-06-15/just me
;
; Example usage:
;    #Include <Class_MySQLAPI>                                       ; include Class_MySQLAPI.ahk from lib
;    My_DB := New MySQLAPI                                           ; instantiate an object using this class
;    My_DB.Connect("Server", "User", "Password")                     ; connect to the server
;    My_DB.Select_DB("Database")                                     ; select a database
;    or
;    My_DB.Real_Connect("Server", "User", "Password", "Database")    ; connect to the server and select a database
;    SQL := "SELECT ..."                                             ; create a SQL statement
;    Result := My_DB.Query(SQL)                                      ; execute the SQL statement
;    ...                                                             ; do something
;    ...                                                             ; do another thing
;    My_DB := ""                                                     ; close the connection and free all resources
;
; Remarks:
; The character encoding depends on the character set used by the current connection. That's why the code page for
; all connections is set to UTF-8 within the __New() meta-function. String conversions are done internally
; whenever possible.
; ======================================================================================================================
Class MySQLAPI {
   ; ===================================================================================================================
   ; CLASS VARIABLES
   ; ===================================================================================================================
   ; MYSQL_FIELD type
   Static FIELD_TYPE := {0: "DECIMAL", 1: "TINY", 2: "SHORT", 3: "LONG", 4: "FLOAT", 5: "DOUBLE", 6: "NULL"
                       , 7: "TIMESTAMP", 8: "LONGLONG", 9: "INT24", 10: "DATE", 11: "TIME", 12: "DATETIME"
                       , 13: "YEAR", 14: "NEWDATE", 15: "VARCHAR", 16: "BIT", 256: "NEWDECIMAL", 247: "ENUM"
                       , 248: "SET", 249: "TINY_BLOB", 250: "MEDIUM_BLOB", 251: "LONG_BLOB", 252: "BLOB"
                       , 253: "VAR_STRING", 254: "STRING", 255: "GEOMETRY"}
   ; MYSQL_FIELD bit-flags
   Static FIELD_FLAG := {NOT_NULL: 1, PRI_KEY: 2, UNIQUE_KEY: 4, MULTIPLE_KEY: 8, BLOB: 16, UNSIGNED: 32
                       , ZEROFILL: 64, BINARY: 128, ENUM: 256, AUTO_INCREMENT: 512, TIMESTAMP: 1024, SET: 2048
                       , NO_DEFAULT_VALUE: 4096, NUM:	32768}
   ; MySQL_SUCCESS
   Static MySQL_SUCCESS := 0
   ; ===================================================================================================================
   ; META FUNCTION __New
   ; Load and initialize libmysql.dll which is supposed to be in the sript's folder.
   ; Parameters:    LibPath  - Optional: Absolute path of libmysql.dll
   ; ===================================================================================================================
   __New(LibPath := "") {
      Static LibMySQL := A_ScriptDir . "\libmysql.dll"
      ; Do not instantiate unstances!
      If (This.Base.Base.__Class = "MySQLAPI") {
         MsgBox, 16, MySQL Error!, You must not instantiate instances of MySQLDB!
         Return False
      }
      ; Load libmysql.dll
      If (LibPath)
         LibMySQL := LibPath
      If !(MySQLM := DllCall("Kernel32.dll\LoadLibrary", "Str", LibMySQL, "UPtr")) {
         If (A_LastError = 126) ; The specified module could not be found
            MsgBox, 16, MySQL Error!, Could not find %LibMySQL%!
         Else {
            ErrCode := A_LastError
            VarSetCapacity(ErrMsg, 131072, 0) ; Unicode
            DllCall("FormatMessage", "UInt", 0x1200, "Ptr", 0, "UInt", ErrCode, "UInt", 0, "Str", ErrMsg, "UInt", 65536, "Ptr", 0)
            MsgBox, 16, MySQL Error!, % "Could not load " . LibMySQL . "!`n"
                                      . "Error code: " . ErrCode . "`n"
                                      . ErrMsg
         }
         Return False
      }
      This.Module := MySQLM
      ; Init MySQL
      If !(MYSQL := This.Init()) {
         MsgBox, 16, MySQL Error!, Could not initialize MySQL!
         Return False
      }
      This.MYSQL := MYSQL
      If (This.Options("MYSQL_SET_CHARSET_NAME", "utf8") <> This.MySQL_SUCCESS) {
         MsgBox, 16, MySQL Error!, Set option MYSQL_SET_CHARSET_NAME failed!
         Return False
      }
      If (This.Options("MYSQL_OPT_RECONNECT", True) <> This.MySQL_SUCCESS) {
         MsgBox, 16, MySQL Error!, Set option MYSQL_OPT_RECONNECT failed!
         Return False
      }
      This.Connected := False
   }
   ; ===================================================================================================================
   ; META FUNCTION __Delete
   ; Free ressources and close the connection, if needed.
   ; ===================================================================================================================
   __Delete() {
      If (This.MYSQL)
         This.Close()
      If (This.Module)
         DllCall("Kernel32.dll\FreeLibrary", "Ptr", This.Module)
   }
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Additional custom functions to get the data of a MYSQL_RES structure
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Converts a MYSQL_FIELD structure and returns an object containing the appropriate keys and values.
   ; Parameters:    MYSQL_FIELD - Pointer to a MYSQL_FIELD structure.
   ; Return values: Field object.
   ; ===================================================================================================================
   GetField(ByRef MYSQL_FIELD) {
      Field := {}
      Offset := 0
      Field.Name      := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.OrgName   := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.Table     := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.OrgTable  := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.DB        := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.Catalog   := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.Default   := StrGet(NumGet(MYSQL_FIELD + 0, Offset, "UPtr"), "UTF-8"), Offset += A_PtrSize
      Field.Length    := NumGet(MYSQL_FIELD + 0, Offset, "UInt"), Offset += 4
      Field.MaxLength := NumGet(MYSQL_FIELD + 0, Offset, "UInt"), Offset += 4 * 8 ; skip string length fields
      Field.Flags     := NumGet(MYSQL_FIELD + 0, Offset, "UInt"), Offset += 4
      Field.Decimals  := NumGet(MYSQL_FIELD + 0, Offset, "UInt"), Offset += 4
      Field.CharSetNr := NumGet(MYSQL_FIELD + 0, Offset, "UInt"), Offset += 4
      Field.Type      := This.FIELD_TYPE[NumGet(MYSQL_FIELD + 0, Offset, "UInt")]
      Return Field
   }
   ; ===================================================================================================================
   ; Returns the values of the next row of the given MYSQL_RES as an array.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure.
   ; Return values: Array of values, False if there is no more row
   ; ===================================================================================================================
   GetNextRow(MYSQL_RES) {
      If (MYSQL_ROW := This.Fetch_Row(MYSQL_RES)) {
         Row := []
         Lengths := This.Fetch_Lengths(MYSQL_RES)
         Loop, % This.Num_Fields(MYSQL_RES) {
            J := A_Index - 1
            If (Len := NumGet(Lengths + 0, 4 * J, "UInt"))
               Row[A_Index] := (StrGet(NumGet(MYSQL_ROW + 0, A_PtrSize * J, "UPtr"), Len, "UTF-8"))
            Else
               Row[A_Index] := ""
         }
         Return Row
      }
      Return False
   }
   ; ===================================================================================================================
   ; Gets the result for the most recent query that successfully produced a result set and returns an object containing
   ; the appropriate keys and values.
   ; Return values: Result object, or False if there is no result.
   ; ===================================================================================================================
   GetResult() {
      If !(MYSQL_RES := This.Store_Result(This.MYSQL))
            Return False
      Result := {}
      Result.Rows := This.Num_Rows(MYSQL_RES)
      Result.Columns := This.Num_Fields(MYSQL_RES)
      Result.Fields := []
      While(MYSQL_FIELD := This.Fetch_Field(MYSQL_RES))
         Result.Fields[A_Index] := This.GetField(MYSQL_FIELD)
      While (Row := This.GetNextRow(MYSQL_RES))
         Result[A_index] := Row
      This.Free_Result(MYSQL_RES)
      Return Result
   }
   GetResultLite() {
      If !(MYSQL_RES := This.Store_Result(This.MYSQL))
            Return False
      Result := {}
     ; Result.Rows := This.Num_Rows(MYSQL_RES)
     ; Result.Columns := This.Num_Fields(MYSQL_RES)
     ; Result.Fields := []
     ; While(MYSQL_FIELD := This.Fetch_Field(MYSQL_RES))
     ;    Result.Fields[A_Index] := This.GetField(MYSQL_FIELD)
      While (Row := This.GetNextRow(MYSQL_RES))
         Result[A_index] := Row
      This.Free_Result(MYSQL_RES)
      Return Result
   }
   ; ===================================================================================================================
   ; Converts the passed string to UTF-8.
   ; Parameters:    Str - String to convert.
   ; Return values: Address of Str.
   ; ===================================================================================================================
   UTF8(ByRef Str) {
      Var := Str, VarSetCapacity(Str, StrPut(Var, "UTF-8"), 0), StrPut(Var, &Str, "UTF-8")
      Return &Str
   }
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; API functions
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; May be called immediately after executing a statement with mysql_query() or mysql_real_query(). It returns the
   ; number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT.
   ; Return values: An integer greater than zero indicates the number of rows affected or retrieved.
   ; ===================================================================================================================
   Affected_Rows() {
      Return DllCall("libmysql.dll\mysql_affected_rows", "Ptr", This.MYSQL, "UInt64")
   }
   ; ===================================================================================================================
   ; Sets autocommit mode on if Mode is 1, off if Mode is 0.
   ; Parameters:    Mode  - 0/1 (False/True)
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   AutoCommit(Mode) {
      Return DllCall("libmysql.dll\mysql_autocommit", "Ptr", This.MYSQL, "Char", Mode, "Char")
   }
   ; ===================================================================================================================
   ; Changes the user and causes the database specified by DB to become the default (current) database on the connection
   ; specified by mysql.
   ; Parameters:    User     - User name
   ;                PassWd   - Password
   ;                DB       - Database name
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Change_User(User, PassWd, DB) {
      Return DllCall("libmysql.dll\mysql_change_user", "Ptr", This.MYSQL, "Ptr", This.UTF8(User)
                  , "Ptr", This.UTF8(PassWd), "Ptr", This.UTF8(DB), "Char")
   }
   ; ===================================================================================================================
   ; Returns a string containing the default character set name for the current connection.
   ; Return values: String.
   ; ===================================================================================================================
   Character_Set_Name() {
      Return ((P := DllCall("libmysql.dll\mysql_character_set_name", "Ptr", This.MYSQL, "UPtr")) ? StrGet(P, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; Closes a previously opened connection.
   ; Return values: None
   ; ===================================================================================================================
   Close() {
      DllCall("libmysql.dll\mysql_close", "Ptr", This.MYSQL)
   }
   ; ===================================================================================================================
   ; Commits the current transaction.
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Commit() {
      Return DllCall("libmysql.dll\mysql_commit", "Ptr", This.MYSQL, "Char")
   }
   ; ===================================================================================================================
   ; This function is deprecated. Use mysql_real_connect() instead.
   ; ===================================================================================================================
   Connect(Host, User, PassWd) {
      Return This.Real_Connect(Host, User, PassWD)
   }
   ; ===================================================================================================================
   ; Creates the database named by the DB parameter.
   ; This function is deprecated. It is preferable to use mysql_query() to issue an SQL CREATE DATABASE statement
   ; instead.
   ; Parameters:    DB    - Database name
   ; Return values: Zero if the database was created successfully. Nonzero if an error occurred.
   ; ===================================================================================================================
   Create_DB(DB) {
      Return DllCall("libmysql.dll\mysql_create_db", "Ptr", This.MYSQL, "Ptr", This.UTF8(DB), "Int")
   }
   ; ===================================================================================================================
   ; Seeks to an arbitrary row in a query result set. The Offset value is a row number.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ;                Offset    - Specify a value in the range from 0 to mysql_num_rows(result)-1.
   ; Return values: None
   ; ===================================================================================================================
   Data_Seek(MYSQL_RES, Offset) {
      DllCall("libmysql.dll\mysql_data_seek", "Ptr", MYSQL_RES, "UInt64", Offset)
   }
   ; ===================================================================================================================
   ; mysql_debug() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Drops the database named by the DB parameter.
   ; This function is deprecated. It is preferable to use mysql_query() to issue an SQL DROP DATABASE statement instead.
   ; Parameters:    DB    - Database name
   ; Return values: Zero if the database was dropped  successfully. Nonzero if an error occurred.
   ; ===================================================================================================================
   Drop_DB(DB) {
      Return DllCall("libmysql.dll\mysql_drop_db", "Ptr", This.MYSQL, "Ptr", This.UTF8(DB), "Int")
   }
   ; ===================================================================================================================
   ; mysql_dump_debug_info() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Determines whether the last row of a result set has been read.
   ; This function is deprecated. mysql_errno() or mysql_error() may be used instead.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ; Return values: Zero if no error occurred. Nonzero if the end of the result set has been reached.
   ; ===================================================================================================================
   EOF(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_eof", "Ptr", MYSQL_RES, "Char")
   }
   ; ===================================================================================================================
   ; Returns the error code for the most recently invoked API function that can succeed or fail.
   ; Return values: An error code value for the last mysql_xxx() call, if it failed. zero means no error occurred.
   ; ===================================================================================================================
   ErrNo() {
      Return DllCall("libmysql.dll\mysql_errno", "Ptr", This.MYSQL, "UInt")
   }
   ; ===================================================================================================================
   ; Returns a null-terminated string containing the error message for the most recently invoked API
   ; function that failed. An empty string indicates no error.
   ; Return values: String.
   ; ===================================================================================================================
   Error() {
      Return ((S := DllCall("libmysql.dll\mysql_error", "Ptr", This.MYSQL, "UPtr")) ? StrGet(S, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; mysql_escape_string() ->  mysql_real_escape_string()
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Returns the definition of the next column of a result set as a MYSQL_FIELD structure.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ; Return values: A pointer to the MYSQL_FIELD structure for the current column. NULL if no columns are left.
   ; ===================================================================================================================
   Fetch_Field(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_fetch_field", "Ptr", MYSQL_RES, "UPtr")
   }
   ; ===================================================================================================================
   ; Given a field number FieldNr for a column within a result set, returns that column's field definition as
   ; a MYSQL_FIELD structure.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ;                FieldNr   - Field number in the range from 0 to mysql_num_fields(result)-1.
   ; Return values: A Pointer to the MYSQL_FIELD structure for the specified column.
   ; ===================================================================================================================
   Fetch_Field_Direct(MYSQL_RES, FieldNr) {
      Return DllCall("libmysql.dll\mysql_fetch_field_direct", "Ptr", MYSQL_RES, "UInt", FieldNr, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns an array of all MYSQL_FIELD structures for a result set. Each structure provides the field definition for
   ; one column of the result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ; Return values: A Pointer to the MYSQL_FIELD structure for the specified column.
   ; ===================================================================================================================
   Fetch_Fields(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_fetch_fields", "Ptr", MYSQL_RES, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the lengths of the columns of the current row within a result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ; Return values: A Pointer to an array of unsigned long integers representing the size of each column
   ;                (not including any terminating null characters). NULL if an error occurred.
   ; ===================================================================================================================
   Fetch_Lengths(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_fetch_lengths", "Ptr", MYSQL_RES, "UPtr")
   }
   ; ===================================================================================================================
   ; Retrieves the next row of a result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ; Return values: A poiner to a MYSQL_ROW structure, NULL when there are no more rows to retrieve or if an error
   ;                occurred.
   ; ===================================================================================================================
   Fetch_Row(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_fetch_row", "Ptr", MYSQL_RES, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the number of columns for the most recent query on the connection.
   ; Return values: An unsigned integer representing the number of columns in a result set.
   ; ===================================================================================================================
   Field_Count() {
      Return DllCall("libmysql.dll\mysql_field_count", "Ptr", This.MYSQL, "UInt")
   }
   ; ===================================================================================================================
   ; Sets the field cursor to the given offset. The next call to mysql_fetch_field() retrieves the field definition
   ; of the column associated with that offset.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ;                Offset    - Specify a value in the range from 0 to mysql_num_fields(result)-1.
   ;                            To seek to the beginning of a row, pass an offset value of zero.
   ; Return values: The previous value of the field cursor.
   ; ===================================================================================================================
   Field_Seek(MYSQL_RES, Offset) {
      Return DllCall("libmysql.dll\mysql_field_seek", "Ptr", MYSQL_RES, "UInt", Offset, "UInt")
   }
   ; ===================================================================================================================
   ; Returns the position of the field cursor used for the last mysql_fetch_field(). This value can be used as
   ; an argument to mysql_field_seek().
   ; Parameters:    MYSQL_RES -  Pointer to a MYSQL_RES structure
   ; Return values: The current offset of the field cursor.
   ; ===================================================================================================================
   Field_Tell(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_field_tell", "Ptr", MYSQL_RES, "UInt")
   }
   ; ===================================================================================================================
   ; Frees the memory allocated for a result set by mysql_store_result(), mysql_use_result(), and so forth.
   ; Parameters:    MYSQL_RES -  Pointer to a MYSQL_RES structure
   ; Return values: None.
   ; ===================================================================================================================
   Free_Result(MYSQL_RES) {
      DllCall("libmysql.dll\mysql_free_result", "Ptr", MYSQL_RES)
   }
   ; ===================================================================================================================
   ; mysql_get_character_set_info() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Returns a string that represents the client library version.
   ; Parameters:    None
   ; Return values: String.
   ; ===================================================================================================================
   Get_Client_Info() {
      Return ((S := DllCall("libmysql.dll\mysql_get_client_info", "UPtr")) ? StrGet(S, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; Returns an integer that represents the client library version. The value has the format XYYZZ where X is the major
   ; version, YY is the release level, and ZZ is the version number within the release level. For example, a value of
   ; 40102 represents a client library version of 4.1.2.
   ; Parameters:    None
   ; Return values: An integer that represents the MySQL client library version.
   ; ===================================================================================================================
   Get_Client_Version() {
      Return DllCall("libmysql.dll\mysql_get_client_version", "Int")
   }
   ; ===================================================================================================================
   ; Returns a string describing the type of connection in use, including the server host name.
   ; Return values: String.
   ; ===================================================================================================================
   Get_Host_Info() {
      Return ((P := DllCall("libmysql.dll\mysql_get_host_info", "Ptr", This.MYSQL, "UPtr")) ? StrGet(P, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; Returns the protocol version used by current connection.
   ; Return values: An unsigned integer representing the protocol version used by the current connection.
   ; ===================================================================================================================
   Get_Proto_Info() {
      Return DllCall("libmysql.dll\mysql_get_proto_info", "Ptr", This.MYSQL, "UInt")
   }
   ; ===================================================================================================================
   ; Returns a string that represents the server version number.
   ; Return values: String.
   ; ===================================================================================================================
   Get_Server_Info() {
      Return ((P := DllCall("libmysql.dll\mysql_get_server_info", "Ptr", This.MYSQL, "UPtr")) ? StrGet(P, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; Returns the version number of the server as an unsigned integer.
   ; Return values: A number that represents the MySQL server version, for example, 5.1.5 is returned as 50105.
   ; ===================================================================================================================
   Get_Server_Version() {
      Return DllCall("libmysql.dll\mysql_get_server_version", "Ptr", This.MYSQL, "UInt")
   }
   ; ===================================================================================================================
   ; mysql_get_ssl_cipher() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_hex_string()     - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Retrieves a string providing information about the most recently executed statement.
   ; Return values: String.
   ; ===================================================================================================================
   Info() {
      Return ((S := DllCall("libmysql.dll\mysql_info", "Ptr", This.MYSQL, "UPtr")) ? StrGet(S, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; Allocates or initializes a MYSQL object suitable for mysql_real_connect().
   ; Parameters:    MYSQL - Pointer to a MYSQL structure, pass NULL to allocate a new object
   ; Return values: An initialized MYSQL* handle. NULL if there was insufficient memory to allocate a new object.
   ; ===================================================================================================================
   Init(MYSQL := 0) {
      Return DllCall("libmysql.dll\mysql_init", "Ptr", MYSQL, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the value generated for an AUTO_INCREMENT column by the previous INSERT or UPDATE statement.
   ; Return values: Generated ID, if any.
   ; ===================================================================================================================
   Insert_ID() {
      Return DllCall("libmysql.dll\mysql_insert_id", "Ptr", This.MYSQL, "UInt64")
   }
   ; ===================================================================================================================
   ; mysql_kill()           - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_library_end()    - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_library_init()   - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_list_dbs()       - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; Returns a result set consisting of field names in the given table that match the expression specified by
   ; the Like parameter.
   ; Parameters:     Table   - Table name
   ;                 Optional: Like - Expression field names have to match
   ;                                  (may contain the wildcard characters '%' or '_')
   ; Return values: A pointer to a MYSQL_RES result set for success. NULL if an error occurred.
   ; ===================================================================================================================
   List_Fields(Table, Like := "") {
      Return DllCall("libmysql.dll\mysql_list_fields", "Ptr", This.MYSQL, "Ptr", This.UTF8(Table)
                   , "Ptr", (Like = "" ? 0 : This.UTF8(Like)), "UPtr")
   }
   ; ===================================================================================================================
   ; mysql_list_processes() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Returns a result set consisting of table names in the current database that match the expression specified
   ; by the Like parameter.
   ; Parameters:     Optional: Like - Expression table names have to match
   ;                                  (may contain the wildcard characters '%' or '_')
   ; Return values: A pointer to a MYSQL_RES result set for success. NULL if an error occurred.
   ; ===================================================================================================================
   List_Tables(Like := "") {
      Return DllCall("libmysql.dll\mysql_list_tables", "Ptr", This.MYSQL
                   , "Ptr", (Like = "" ? 0 : This.UTF8(Like)), "UPtr")
   }
   ; ===================================================================================================================
   ; This function is used when you execute multiple statements specified as a single statement string, or when you
   ; execute CALL statements, which can return multiple result sets.
   ; Return values: TRUE (1) if more results exist. FALSE (0) if no more results exist.
   ; ===================================================================================================================
   More_Results() {
      Return DllCall("libmysql.dll\mysql_more_results", "Ptr", This.MYSQL, "Char")
   }
   ; ===================================================================================================================
   ; This function is used when you execute multiple statements specified as a single statement string, or when you use
   ; CALL statements to execute stored procedures, which can return multiple result sets.
   ; Return values:  0 : Successful and there are more results.
   ;                -1 : Successful and there are no more results.
   ;                >0 : An error occurred.
   ; ===================================================================================================================
   Next_Result() {
      Return DllCall("libmysql.dll\mysql_next_result", "Ptr", This.MYSQL, "Int")
   }
   ; ===================================================================================================================
   ; Returns the number of columns in a result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure.
   ; Return values: An unsigned integer representing the number of columns in a result set.
   ; ===================================================================================================================
   Num_Fields(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_num_fields", "Ptr", MYSQL_RES, "UInt")
   }
   ; ===================================================================================================================
   ; Returns the number of rows in a result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure.
   ; Return values: An unsigned 64-bit integer representing the number of rows in a result set.
   ; ===================================================================================================================
   Num_Rows(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_num_rows", "Ptr", MYSQL_RES, "UInt64")
   }
   ; ===================================================================================================================
   ; Can be used to set extra connect options and affect behavior for a connection.
   ; This function may be called multiple times to set several options.
   ; Parameters:    Option - The option that you want to set.
   ;                Arg    - The value for the option.
   ; Return values: Zero for success. Nonzero if you specify an unknown option.
   ; ===================================================================================================================
   Options(Option, Arg) {
      Static MySQL_Option := {MYSQL_OPT_CONNECT_TIMEOUT: 0, MYSQL_OPT_COMPRESS: 1, MYSQL_OPT_NAMED_PIPE: 2
                            , MYSQL_INIT_COMMAND: 3, MYSQL_READ_DEFAULT_FILE: 4, MYSQL_READ_DEFAULT_GROUP: 5
                            , MYSQL_SET_CHARSET_DIR: 6, MYSQL_SET_CHARSET_NAME: 7, MYSQL_OPT_LOCAL_INFILE: 8
                            , MYSQL_OPT_PROTOCOL: 9, MYSQL_SHARED_MEMORY_BASE_NAME: 10, MYSQL_OPT_READ_TIMEOUT: 11
                            , MYSQL_OPT_WRITE_TIMEOUT: 12, MYSQL_OPT_USE_RESULT: 13
                            , MYSQL_OPT_USE_REMOTE_CONNECTION: 14, MYSQL_OPT_USE_EMBEDDED_CONNECTION: 15
                            , MYSQL_OPT_GUESS_CONNECTION: 16, MYSQL_SET_CLIENT_IP: 17, MYSQL_SECURE_AUTH: 18
                            , MYSQL_REPORT_DATA_TRUNCATION: 19, MYSQL_OPT_RECONNECT: 20
                            , MYSQL_OPT_SSL_VERIFY_SERVER_CERT: 21, MYSQL_PLUGIN_DIR: 22, MYSQL_DEFAULT_AUTH: 23
                            , MYSQL_ENABLE_CLEARTEXT_PLUGIN: 24}
      If Option Is Not Integer
         Option := MYSQL_Option[Option]
      If Arg Is Integer
         Return DllCall("libmysql.dll\mysql_options", "Ptr", This.MYSQL, "Int", Option, "Int64P", Arg, "Int")
      Return DllCall("libmysql.dll\mysql_options", "Ptr", This.MYSQL, "Int", Option, "Ptr", This.UTF8(Arg), "Int")
   }
   ; ===================================================================================================================
   ; Checks whether the connection to the server is working.
   ; Return values: Zero if the connection to the server is active. Nonzero if an error occurred.
   ; ===================================================================================================================
   Ping() {
      Return DllCall("libmysql.dll\mysql_ping", "Ptr", This.MYSQL, "Int")
   }
   ; ===================================================================================================================
   ; Executes the SQL statement pointed to by the null-terminated string SQL.
   ; Parameters:    SQL   - SQL statement.
   ; Return values: Zero if the statement was successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Query(SQL) {
      Return DllCall("libmysql.dll\mysql_query", "Ptr", This.MYSQL, "Ptr", This.UTF8(SQL), "Int")
   }
   ; ===================================================================================================================
   ; Attempts to establish a connection to a MySQL database engine running on Host.
   ; Parameters:    Host   - A host name or an IP address.
   ;                User   - The user's MySQL login ID.
   ;                PassWd - The password for user.
   ;             Optional:
   ;                DB     - The database name.
   ;                Port   - The port number for the TCP/IP connection (Default: 3306)
   ;                Socket - A string specifying the socket or named pipe to use.
   ;                Flags  - Flags to enable certain features.
   ; Return values: A MYSQL* connection handle if the connection was successful, NULL if the connection was
   ;                unsuccessful. For a successful connection, the return value is the same as the handle passed to
   ;                mysql_real_connect() in the first parameter.
   ; ===================================================================================================================
   /*
   Query2Obj(SQL){
    This.Query(SQL)
    out := {}
    resultPtr := This.Store_Result()
    if resultPtr > 0
    {
        out.fieldCount := fieldCount := This.Field_Count()
        out.rowCount := rowCount := This.Num_Rows()
        out.data := []
        Loop
        {
            rowid := A_Index
            row := This.Fetch_Row(resultPtr)
            If (row = 0 || row == "")
                Break
            out.data[rowid] := []
            lengths := This.Fetch_Lengths(resultPtr)
            Loop % fieldCount
            {
                J := A_Index - 1
                If (Len := NumGet(Lengths + 0, 4 * J, "UInt"))
                    field := (StrGet(NumGet(row + 0, A_PtrSize * J, "UPtr"), Len, "UTF-8"))
                else
                    field=
                out.data[rowid].push(field)
            }
        }
    }
    return out
   }
   */

   Real_Connect(Host, User, PassWd, DB := "", Port := 3306, Socket := 0, Flags := 0) {
      If (DB = "")
         PtrDB := 0
      Else
         PtrDB := This.UTF8(DB)
      If !(MYSQL := DllCall("libmysql.dll\mysql_real_connect", "Ptr", This.MYSQL, "Ptr", This.UTF8(Host)
                          , "Ptr", This.UTF8(User), "Ptr", This.UTF8(PassWd), "Ptr", PtrDB
                          , "UInt", Port, "Ptr", This.UTF8(Socket), "Uint", Flags, "UPtr"))
         Return False
      Return MYSQL

   }
   ; ===================================================================================================================
   ; This function is used to create a legal SQL string that you can use in an SQL statement.
   ; The string in From is encoded to an escaped SQL string, taking into account the current character set of the
   ; connection.
   ; Parameters:    From   - Source string.
   ; Return values: Escaped string.
   ; ===================================================================================================================
   Real_Escape_String(ByRef From) {
      L := StrPut(From, "UTF-8") - 1
      VarSetCapacity(SI, L, 0)
      StrPut(From, &SI, "UTF-8")
      VarSetCapacity(SO, (L * 2) + 1, 0)
      N := DllCall("libmysql.dll\mysql_real_escape_string", "Ptr", This.MYSQL, "Ptr", &SO, "Ptr", &SI, "UInt", L, "UInt")
      Return StrGet(&SO, N, "UTF-8")
   }
   ; ===================================================================================================================
   ; Executes the SQL statement pointed to by SQL, a string Length bytes long.
   ; mysql_query() cannot be used for statements that contain binary data; you must use mysql_real_query() instead.
   ; All strings within the SQL statement have to be UTF-8.
   ; Parameters:    SQL    - SQL statement.
   ;                Length - Length of the statement in bytes.
   ; Return values: Zero if the statement was successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Real_Query(ByRef SQL, Length) {
      Return DllCall("libmysql.dll\mysql_real_query", "Ptr", This.MYSQL, "Ptr", &SQL, "UInt", Length, "Int")
   }
   ; ===================================================================================================================
   ; mysql_refresh() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_reload()  - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Rolls back the current transaction.
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Rollback() {
      Return DllCall("libmysql.dll\mysql_rollback", "Ptr", This.MYSQL, "Char")
   }
   ; ===================================================================================================================
   ; Sets the row cursor to an arbitrary row in a query result set.
   ; Parameters:    MYSQL_RES - Pointer to a MYSQL_RES structure
   ;                Offset    - The offset value is a row offset, typically a value returned from mysql_row_tell()
   ;                            or from mysql_row_seek(). This value is not a row number.
   ; Return values: The previous value of the row cursor.
   ; ===================================================================================================================
   Row_Seek(MYSQL_RES, Offset) {
      Return DllCall("libmysql.dll\mysql_row_seek", "Ptr", MYSQL_RES, "Ptr", Offset, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the current position of the row cursor for the last mysql_fetch_row(). This value can be used as an
   ; argument to mysql_row_seek().
   ; Parameters:    MYSQL_RES -  Pointer to a MYSQL_RES structure
   ; Return values: The current offset of the row cursor.
   ; ===================================================================================================================
   Row_Tell(MYSQL_RES) {
      Return DllCall("libmysql.dll\mysql_row_tell", "Ptr", MYSQL_RES, "UPtr")
   }
   ; ===================================================================================================================
   ; Causes the database specified by DB to become the default (current) database on the connection specified by mysql.
   ; In subsequent queries, this database is the default for table references that do not include an explicit database
   ; specifier.
   ; Parameters:    DB     - Database name.
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Select_DB(DB) {
      Return DllCall("libmysql.dll\mysql_select_db", "Ptr", This.MYSQL, "Ptr", This.UTF8(DB), "Int")
   }
   ; ===================================================================================================================
   ; This function is used to set the default character set for the current connection.
   ; Parameters:    CSName - Character set name.
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Set_Character_Set(CSName) {
      Return DllCall("libmysql.dll\mysql_set_character_set", "Ptr", This.MYSQL, "Ptr", This.UTF8(CSName), "Int")
   }
   ; ===================================================================================================================
   ; mysql_set_local_infile_default() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; mysql_set_local_infile_handler() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Enables or disables an option for the connection.
   ; Parameters:    Option - MYSQL_OPTION_MULTI_STATEMENTS_ON  = 0
   ;                         MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1
   ; Return values: Zero if successful. Nonzero if an error occurred.
   ; ===================================================================================================================
   Set_Server_Option(Option) {
      Return DllCall("libmysql.dll\mysql_set_server_option", "Ptr", This.MYSQL, "Int", Option, "Int")
   }
   ; ===================================================================================================================
   ; mysql_shutdown() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Returns a null-terminated string containing the SQLSTATE error code for the most recently executed SQL statement.
   ; The error code consists of five characters. '00000' means 鈥渘o error.鈥?
   ; Return values: A null-terminated character string containing the SQLSTATE error code.
   ; ===================================================================================================================
   SQLState() {
      Return ((P := DllCall("libmysql.dll\mysql_sqlstate", "Ptr", This.MYSQL, "UPtr")) ? StrGet(P, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; mysql_ssl_set() - not implemented <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   ; ===================================================================================================================
   ; ===================================================================================================================
   ; Returns a character string containing information similar to that provided by the mysqladmin status command.
   ; Return values: A character string describing the server status. NULL if an error occurred.
   ; ===================================================================================================================
   Stat() {
      Return ((P := DllCall("libmysql.dll\mysql_stat", "Ptr", This.MYSQL, "UPtr")) ? StrGet(P, "UTF-8") : "")
   }
   ; ===================================================================================================================
   ; After invoking mysql_query() or mysql_real_query(), you must call mysql_store_result() or mysql_use_result() for
   ; every statement that successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE, and so
   ; forth).
   ; Return values: A pointer to a MYSQL_RES result structure with the results. NULL (0) if an error occurred.
   ; ===================================================================================================================
   Store_Result() {
      Return DllCall("libmysql.dll\mysql_store_result", "Ptr", This.MYSQL, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the thread ID of the current connection.
   ; Return values: The thread ID of the current connection.
   ; ===================================================================================================================
   Thread_ID() {
      Return DllCall("libmysql.dll\mysql_thread_id", "Ptr", This.MYSQL, "UInt")
   }
   ; ===================================================================================================================
   ; After invoking mysql_query() or mysql_real_query(), you must call mysql_store_result() or mysql_use_result() for
   ; every statement that successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE, and so
   ; forth).
   ; Return values: A pointer to a MYSQL_RES result structure with the results. NULL (0) if an error occurred.
   ; ===================================================================================================================
   Use_Result() {
      Return DllCall("libmysql.dll\mysql_use_result", "Ptr", This.MYSQL, "UPtr")
   }
   ; ===================================================================================================================
   ; Returns the number of errors, warnings, and notes generated during execution of the previous SQL statement.
   ; Return values: The warning count.
   ; ===================================================================================================================
   Warning_Count() {
      Return DllCall("libmysql.dll\mysql_warning_count", "Ptr", This.MYSQL, "UInt")
   }
}


Elastix 2.5的系统是Centos 5.9,Asterisk 11。在测试dialpan拨号方案使用odbc mysql的时候报错驱动/usr/lib64/libmyodbc3_r.so找不到,经验证是系统的mysql-connector-odbc没有安装。

在通过yum安装的时候又发现源已经停止服务了,无法下载,找到一个国外源fq下载完,在另外一台机子上则是选择本地安装yum包,下载地址:

https://centos.pkgs.org/5/centos-x86_64/mysql-connector-odbc-3.51.26r1127-2.el5.x86_64.rpm.html  (x64)

https://centos.pkgs.org/5/centos-i386/mysql-connector-odbc-3.51.26r1127-2.el5.i386.rpm.html (x86)

下载完后可以放到当前目录 shell执行:

yum -y localinstall mysql-connector-odbc-3.51.26r1127-2.el5.x86_64.rpm

安装完成后还需配置/etc/odbc.ini:

[MYSQL-asteriskcdrdb]
Description = MySQL connection to 'asterisk' database
Driver = MySQL
Database = asteriskcdrdb
Server = localhost
Port = 3306
Socket = /var/lib/mysql/mysql.sock
User = root
Password = MyPass
Option = 3

配置完成后可以在shell中测试:

[root@Elastix ~]# isql -v MYSQL-asteriskcdrdb
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> show tables;
+-----------------------------------------------------------------+
| Tables_in_asteriskcdrdb                                         |
+-----------------------------------------------------------------+
| cdr                                                             |
+-----------------------------------------------------------------+
SQLRowCount returns 1
1 rows fetched

这就算完成了一半,还需在/etc/asterisk/res_odbc.conf中配置dsn:

[asteriskcdrdb]
enabled=>yes
dsn=>MySQL-asteriskcdrdb
pooling=>no
limit=>1
pre-connect=>yes
share_connections => yes
isolation => repeatable_read
forcecommit => yes

在/etc/asterisk/func_odbc.conf中配置自定义函数(此处dsn指res_odbc.conf中的[name]):

[SQL]
dsn=asteriskcdrdb
readsql=${ARG1}
synopsis=ODBC_SQL(sql)

具体配置说明详见:https://wiki.asterisk.org/wiki/display/AST/Getting+Asterisk+Connected+to+MySQL+via+ODBC

http://www.asteriskdocs.org/en/3rd_Edition/asterisk-book-html-chunk/getting_funky.html

配置完后注意在Asterisk CLI中执行reload或者shell执行:

asterisk -x reload

最后就可以在dialpan中测试使用了,如下面的例子(/etc/asterisk/extensions.conf)拨打876在asterisk日志中输出结果:

[from-internal]
exten => 876,1,Answer
exten => 876,n,Noop(${ODBC_SQL("select now()")})
exten => 876,n,Noop(${ODBC_SQL("select top 1 uniquid from cdr order by calldate desc")})
exten => 876,n,Background(star)
exten => 876,n,Wait(60)
include => from-internal-noxfer
include => from-internal-xfer
include => bad-number ; auto-generated


ProcessExtensions扩展取自https://github.com/murrayju/CreateProcessAsUser


近几天在使用system权限执行cmd的时候遇到程序不会在当前桌面用户会话下显示,通过测试找到了通过CreateProcessAsUser和获取用户token的解决方案,做了个控制台程序,下面是部分代码:

  class Program
    {
        static void Main(string[] args)
        {
            switch (args.Length)
            {
                case 1:
                    ProcessExtensions.StartProcessAsCurrentUser(args[0]);
                    break;
                case 2:
                    ProcessExtensions.StartProcessAsCurrentUser(args[0], args[1]);
                    break;
                case 3:
                    ProcessExtensions.StartProcessAsCurrentUser(args[0], args[1], args[2]);
                    break;
                default:
                    Console.WriteLine("example:psrunas notepad.exe paraments workingdir");
                    break;
            }
        }
    }

完整工程请下载:psrunas.zip

LanProxy JAVA编写的内网穿透解决方案及详细说明 1458

作者为 发表

网络路由

部分内容引用遇见,http://www.zuidaima.com/share/3659323964050432.htm上发表的内容。

目前国内部分地区的宽带运营商已经不再提供公网IP地址的服务了,或者当服务环境在防火墙和路由器后面的私网的时候,我们就需要通过内网穿透(打洞)形式访问我们在私网部署的服务。

目前国内的服务商有花生壳和nat123,都是要收费且不能静默部署的,虚拟专用网络连接有的时候有和需求不符。目前开源的穿透方案有ngrok、n2n、lanproxy等,下面我们来介绍下lanproxy。

LanProxy(下载)是一个JAVA便携的内网穿透解决方案,开源地址:https://github.com/ffay/lanproxy

服务端支持linux/Windows,客户端支持linux/Windows和部分嵌入式系统(下载


环境:

    jdk1.7+

   一台外网服务器   有固定ip  这里假设外网ip为10.10.21.22   操作系统linux/windows

服务端配置步骤:

     1. 下载的zip文件解压出来, 打开proxy-server-0.1/conf/config.properties文件,ssl默认是开启的 服务端口4993 ,如果不需要的话可以改为false 服务端口4900。

       搭建自己的内网穿透服务器~

   2. 在proxy-server-0.1/bin目录   windows执行startup.bat    linux执行./startup.sh,   然后就可以在服务端8090端口访问了,账号密码就是config.properties里配置的admin/admin

搭建自己的内网穿透服务器~

  3.  进入网页后点击添加客户端,点击提交,记住客户端的秘钥。方便给客户端使用。可以建立多个客户端,到时候同事要用可以分配一个客户端就好。

搭建自己的内网穿透服务器~

   4. 添加客户端后  左侧导航栏会出现客户端名称,点击然后添加配置、

     代理名称可以描述一下你的服务  比如我要外放mysql服务  就叫mysqlservice好了

     公网端口就是你外网想访问的端口号 也就是外网服务器的某个端口号,配置多个的时候公网端口号不能重复配置。假如这里我外放27036接口

   后端ip端口就是你分配到那台客户端的ip和端口   ip固定127.0.0.1就好,端口根据实际情况,比如是外放mysql 那么就是127.0.0.1:3306

搭建自己的内网穿透服务器~

客户端配置步骤:

   1、 将proxy-client-0.1文件加拷贝到客户端机器上,linux/windows均可。

   2、 修改proxy-client-0.1/conf/config.properties文件

      这里的client.key 就是我们服务端配置的第3步得到的秘钥。

      ssl这里因为服务器是false  这里也配置false就好。

      server.host就是服务端的固定ip地址

  搭建自己的内网穿透服务器~

3. 配置完后在proxy-client-0.1/bin目录  windows执行startup.bat,  linux执行./startup.sh

  然后在服务端的网页的客户端列表里就可以看到客户端已经在线了。  

  这就说明内网穿透已经配置成功。

  然后你就可以使用10.10.21.22:27036的外网地址 访问到你本机的127.0.0.1:3306的本地数据库了。

  这里支持tcp的任何上层协议。

搭建自己的内网穿透服务器~


以上配置文件中的SSL配置说明:

ssl.jks:通过java的keytool生成的ssl证书,有管理密码和口令密码,生成方法详见百度经验

server.ssl.keyStorePassword=口令密码

server.ssl.keyManagerPassword=管理密码

服务端和客户端使用同一证书。


服务端web管理界面配置说明:

config.server.bind=0.0.0.0 (默认0.0.0.0 绑定特定网卡,填写改网卡IP)

config.server.port=8090 (web端口)

config.admin.username=admin (用户名)

config.admin.password=admin (密码)


JAVA环境说明:

需要java 1.7+环境,安装jre或者jdk后需要配置环境变量,具体方法可以搜索。

服务器是CentOS的话shell执行yum -y install java即可安装。

如果想免安装部署可以提取jre的目录到客户端或服务端目录,重命名成jre(和bin、conf同级),然后修改bin下的startup.bat(第一行后面添加三行):

@echo off & setlocal enabledelayedexpansion
setlocal
SET JAVA_HOME=..\jre\
SET PATH=%JAVA_HOME%\bin;


然后通过srvany.exe注册为服务就可以开机后台自动运行。方法详见通过srvany.exe为任意程序创建服务编写

通过srvany.exe为任意程序创建服务 840

作者为 发表

IT

首先,下载srvany.exe到任意目录,然后以管理员权限运行cmd,输入

sc create 服务名 binpath= "c:\xxxx\srvany.exe" start= auto

创建完成服务,然后打开注册表(regedit.exe),找到“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\服务名”项目

如果该服务名下没有Parameters项目,则对服务名称项目右击新建项,名称为Parameters,然后定位到Parameters项,新建以下几个字符串值。

名称 Application 值为你要作为服务运行的程序地址。

名称 AppDirectory 值为你要作为服务运行的程序所在文件夹路径。

名称 AppParameters 值为你要作为服务运行的程序启动所需要的参数。


当然也可以通过保存注册表*.reg文件双击导入配置:

Windows Registry Editor Version 5.00 
 
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\服务名称\Parameters] 
"Application"="值为你要作为服务运行的程序地址"
"AppDirectory"="值为你要作为服务运行的程序所在文件夹路径"
"AppParameters"="值为你要作为服务运行的程序启动所需要的参数"


sc create的用法:

描述:

        在注册表和服务数据库中创建服务项。

用法:

        sc <server> create [service name] [binPath= ] <option1> <option2>…

 

选项:

注意: 选项名称包括等号。

      等号和值之间需要一个空格。

 type= <own|share|interact|kernel|filesys|rec>

       (默认 = own)

 start= <boot|system|auto|demand|disabled|delayed-auto>

       (默认 = demand)

 error= <normal|severe|critical|ignore>

       (默认 = normal)

 binPath= <BinaryPathName>

 group= <LoadOrderGroup>

 tag= <yes|no>

 depend= <依存关系(以 / (斜杠) 分隔)>

 obj= <AccountName|ObjectName>

       (默认 = LocalSystem)

 DisplayName= <显示名称>

 password= <密码>


json文本数据与obj互转 Autohotkey 926

作者为 发表

Autohotkey

ahk官方论坛转载

json_fromobj( obj ) {
	
	If IsObject( obj )
	{
		isarray := 0 ; an empty object could be an array... but it ain't, says I
		for key in obj
			if ( key != ++isarray )
			{
				isarray := 0
				Break
			}
		
		for key, val in obj
			str .= ( A_Index = 1 ? "" : "," ) ( isarray ? "" : json_fromObj( key ) ":" ) json_fromObj( val )
		
		return isarray ? "[" str "]" : "{" str "}"
	}
	else if obj IS NUMBER
		return obj
	;	else if obj IN null,true,false ; AutoHotkey does not natively distinguish these
	;		return obj
	
	; Encode control characters, starting with backslash.
	StringReplace, obj, obj, \, \\, A
	StringReplace, obj, obj, % Chr(08), \b, A
	StringReplace, obj, obj, % A_Tab, \t, A
	StringReplace, obj, obj, `n, \n, A
	StringReplace, obj, obj, % Chr(12), \f, A
	StringReplace, obj, obj, `r, \r, A
	StringReplace, obj, obj, ", \", A
	StringReplace, obj, obj, /, \/, A
	While RegexMatch( obj, "[^\x20-\x7e]", key )
	{
		str := Asc( key )
		val := "\u" . Chr( ( ( str >> 12 ) & 15 ) + ( ( ( str >> 12 ) & 15 ) < 10 ? 48 : 55 ) )
		. Chr( ( ( str >> 8 ) & 15 ) + ( ( ( str >> 8 ) & 15 ) < 10 ? 48 : 55 ) )
		. Chr( ( ( str >> 4 ) & 15 ) + ( ( ( str >> 4 ) & 15 ) < 10 ? 48 : 55 ) )
		. Chr( ( str & 15 ) + ( ( str & 15 ) < 10 ? 48 : 55 ) )
		StringReplace, obj, obj, % key, % val, A
	}
	return """" obj """"
}

json_toobj(str){
	
	quot := """" ; firmcoded specifically for readability. Hardcode for (minor) performance gain
	ws := "`t`n`r " Chr(160) ; whitespace plus NBSP. This gets trimmed from the markup
	obj := {} ; dummy object
	objs := [] ; stack
	keys := [] ; stack
	isarrays := [] ; stack
	literals := [] ; queue
	y := nest := 0
	
	; First pass swaps out literal strings so we can parse the markup easily
	StringGetPos, z, str, %quot% ; initial seek
	while !ErrorLevel
	{
		; Look for the non-literal quote that ends this string. Encode literal backslashes as '\u005C' because the
		; '\u..' entities are decoded last and that prevents literal backslashes from borking normal characters
		StringGetPos, x, str, %quot%,, % z + 1
		while !ErrorLevel
		{
			StringMid, key, str, z + 2, x - z - 1
			StringReplace, key, key, \\, \u005C, A
			If SubStr( key, 0 ) != "\"
				Break
			StringGetPos, x, str, %quot%,, % x + 1
		}
		;	StringReplace, str, str, %quot%%t%%quot%, %quot% ; this might corrupt the string
		str := ( z ? SubStr( str, 1, z ) : "" ) quot SubStr( str, x + 2 ) ; this won't
		
		; Decode entities
		StringReplace, key, key, \%quot%, %quot%, A
		StringReplace, key, key, \b, % Chr(08), A
		StringReplace, key, key, \t, % A_Tab, A
		StringReplace, key, key, \n, `n, A
		StringReplace, key, key, \f, % Chr(12), A
		StringReplace, key, key, \r, `r, A
		StringReplace, key, key, \/, /, A
		while y := InStr( key, "\u", 0, y + 1 )
			if ( A_IsUnicode || Abs( "0x" SubStr( key, y + 2, 4 ) ) < 0x100 )
				key := ( y = 1 ? "" : SubStr( key, 1, y - 1 ) ) Chr( "0x" SubStr( key, y + 2, 4 ) ) SubStr( key, y + 6 )
		
		literals.insert(key)
		
		StringGetPos, z, str, %quot%,, % z + 1 ; seek
	}
	
	; Second pass parses the markup and builds the object iteratively, swapping placeholders as they are encountered
	key := isarray := 1
	
	; The outer loop splits the blob into paths at markers where nest level decreases
	Loop Parse, str, % "]}"
	{
		StringReplace, str, A_LoopField, [, [], A ; mark any array open-brackets
		
		; This inner loop splits the path into segments at markers that signal nest level increases
		Loop Parse, str, % "[{"
		{
			; The first segment might contain members that belong to the previous object
			; Otherwise, push the previous object and key to their stacks and start a new object
			if ( A_Index != 1 )
			{
				objs.insert( obj )
				isarrays.insert( isarray )
				keys.insert( key )
				obj := {}
				isarray := key := Asc( A_LoopField ) = 93
			}
			
			; arrrrays are made by pirates and they have index keys
			if ( isarray )
			{
				Loop Parse, A_LoopField, `,, % ws "]"
					if ( A_LoopField != "" )
						obj[key++] := A_LoopField = quot ? literals.remove(1) : A_LoopField
			}
			; otherwise, parse the segment as key/value pairs
			else
			{
				Loop Parse, A_LoopField, `,
					Loop Parse, A_LoopField, :, % ws
						if ( A_Index = 1 )
							key := A_LoopField = quot ? literals.remove(1) : A_LoopField
				else if ( A_Index = 2 && A_LoopField != "" )
					obj[key] := A_LoopField = quot ? literals.remove(1) : A_LoopField
			}
			nest += A_Index > 1
		} ; Loop Parse, str, % "[{"
		
		If !--nest
			Break
		
		; Insert the newly closed object into the one on top of the stack, then pop the stack
		pbj := obj
		obj := objs.remove()
		obj[key := keys.remove()] := pbj
		If ( isarray := isarrays.remove() )
			key++
		
	} ; Loop Parse, str, % "]}"
	
	Return obj
}


JSON POST Autohotkey 1060

作者为 发表

Autohotkey

JSONPOST(url, Encoding = "",postData=""){ ;网址,编码, post JSON数据
	hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Try
	{
		hObject.Open("POST",url,False)
		hObject.SetRequestHeader("Content-Type", "application/json")
		hObject.Send(postData)
	}
	catch e
		return -1

	if (Encoding && hObject.ResponseBody)
	{
		oADO := ComObjCreate("adodb.stream")
		oADO.Type := 1
		oADO.Mode := 3
		oADO.Open()
		oADO.Write(hObject.ResponseBody)
		oADO.Position := 0
		oADO.Type := 2
		oADO.Charset := Encoding
		return oADO.ReadText(), oADO.Close()
	}
	return hObject.ResponseText
}


获取生成32位UUID GUID Autohotkey 1024

作者为 发表

Autohotkey

;生成32位UUID
GUID(){
	shellobj := ComObjCreate("Scriptlet.TypeLib")
	ret := shellobj.GUID
	uuid := RegExReplace(ret,"(\{|\}|-)","") ;去掉花括号和-
	return uuid
}


生成随机时间 日期加减 Autohotkey 1290

作者为 发表

Autohotkey

MsgBox % GenTime()


;生成随机时间 前1小时-前三天内
GenTime(){
	FormatTime, outdate, % Time_unix2human(Time_human2unix(A_Now)+rand(28800,35000)), yyyy-MM-dd HH:mm:ss
	return outdate
}


rand(min,max){ ;随机函数
	Random, out, % min, max
	return out
}

;unix时间戳转换函数
Time_unix2human(time)
{
        human=19700101000000
        time-=((A_NowUTC-A_Now)//10000)*3600        ;时差
        human+=%time%,Seconds
        return human
        }
Time_human2unix(time)
{
        time-=19700101000000,Seconds
        time+=((A_NowUTC-A_Now)//10000)*3600        ;时差
        return time
}



友情链接:Autohotkey中文论坛Autohotkey中文帮助Autohotkey官网我的B站直播间如若生涯一场梦博客联系作者免GooglePlay APK下载

 主题设计 • skyfrit.com  Thinkai's Blog | 保留所有权利

46 queries in 1.266 seconds |