VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

找出安裝於電腦裡 MySQL ODBC 最新版本

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
garfield
Site Admin


註冊時間: 2003-01-30
文章: 2160


第 1 樓

發表發表於: 星期五 八月 30, 2013 11:53 am    文章主題: 找出安裝於電腦裡 MySQL ODBC 最新版本 引言回覆

1.VFP是32位元軟體, 所以MyODBC 要安裝32bit 才能使用.

2.連接字串 :
mstring = [DRIVER={]+GetLastODBCName( MySQL ODBC')+[};SERVER=localhost;UID=root;PWD=密碼;Stmt=set names utf8;database=後端資料庫名;charset=utf8]

代碼:

? 'MySQL ODBC 最新版本:',GetLastODBCName('MySQL ODBC')
RETURN

PROCEDURE GetLastODBCName
LPARAMETERS modbc
IF EMPTY(modbc)
   modbc = 'MySQL ODBC'
ENDIF
LOCAL mreg
mreg = Createobject( 'Registry' )
*? mreg.ReadRegistryString( HKEY_LOCAL_MACHINE ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\","MySQL ODBC 5.2 Unicode Driver" )

LOCAL mret ,i
mret = ''
local mlist[1,1]
*mreg.GetEnumValues(@mlist , HKEY_LOCAL_MACHINE ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\" )
mreg.GetEnumValues(@mlist , 0x80000002 ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\" )
FOR i=1 TO ALen(mlist,1)
   *? i,mlist[i,1]      &&-,mlist[i,2]
   IF modbc $ mlist[i,1]
      &&--取最後一個
      mret = mlist[i,1]
   endif
next
RETURN mret

*************************************************************
*** The following should be placed into a .H file and included
*** in any program that uses the Registry class (registry.vcx)

#Define MAX_INI_BUFFERSIZE 256

#Define MAX_INI_ENUM_BUFFERSIZE 16000

*** Registry roots - You'll likely need these values in your programs
*** so add them to FOXPRO.H or to each program that
*** uses them.

#Define HKEY_CLASSES_ROOT -2147483648 && (( HKEY ) 0x80000000 )
#Define HKEY_CURRENT_USER -2147483647 && (( HKEY ) 0x80000001 )
#Define HKEY_LOCAL_MACHINE -2147483646 && (( HKEY ) 0x80000002 )
#Define HKEY_USERS -2147483645 && (( HKEY ) 0x80000003 )

*** Success Flag

#Define ERROR_SUCCESS   0

*** Registry Value types

#Define REG_NONE   0   && Undefined Type (default)
#Define REG_SZ    1   && Regular Null Terminated String
#Define REG_BINARY   3   && ??? (unimplemented)
#Define REG_DWORD   4   && Long Integer value
#Define MULTI_SZ   7   && Multiple Null Term Strings (not implemented)


Define Class Registry As Custom
*************************************************************
*** Author: Rick Strahl
*** modify some error by Garfield
*** (c) West Wind Technologies, 1995
*** Contact: (503) 386-2087 / 76427,2363@compuserve.com
*** Modified: 02/24/95
***
*** Function: Provides read and write access to the
*** System Registry under Windows 95 and
*** NT. The functionality provided is
*** greatly abstracted resulting in using
*** a single method call to set and
*** retrieve values from the registry.
*** The functionality closely matches
*** the way GetPrivateProfileString
*** works, including the ability to
*** automatically delete key nodes.
***
*** Wish List: Key Enumeration and enumerated deletion
*** Allow Binary Registry values
*************************************************************

*** Custom Properties

*** Stock Properties

************************************************************************
* Registry :: Init
*********************************
*** Function: Loads required DLLs. Note Read and Write DLLs are
*** not loaded here since they need to be reloaded each
*** time depending on whether String or Integer values
*** are required
************************************************************************
   Function Init

*** Open Registry Key
   Declare Integer RegOpenKey ;
      IN Win32API ;
      INTEGER nHKey,;
      STRING cSubKey,;
      INTEGER @nHandle

*** Create a new Key
   Declare Integer RegCreateKey ;
      IN Win32API ;
      INTEGER nHKey,;
      STRING cSubKey,;
      INTEGER @nHandle

*** Close an open Key
   Declare Integer RegCloseKey ;
      IN Win32API ;
      INTEGER nHKey

*** Delete a key (path)
   Declare Integer RegDeleteKey ;
      IN Win32API ;
      INTEGER nHKEY,;
      STRING cSubkey

*** Delete a value from a key
   Declare Integer RegDeleteValue ;
      IN Win32API ;
      INTEGER nHKEY,;
      STRING cEntry

   Endproc
* LoadRegistryDLLs

************************************************************************
* Registry :: ReadRegistryString
*********************************
*** Function: Reads a string value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to retrieve
*** Return: Registry String or .NULL. on error
************************************************************************
   Function ReadRegistryString
   Lparameters tnHKey, tcSubkey, tcEntry
   Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)

   lnRegHandle=0

*** Open the registry key
   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here it's STRING.
   Declare Integer RegQueryValueEx ;
      IN Win32API As RegQueryString;
      INTEGER nHKey,;
      STRING lpszValueName,;
      INTEGER dwReserved,;
      INTEGER @lpdwType,;
      STRING @lpbData,;
      INTEGER @lpcbData

*** Return buffer to receive value
   lcDataBuffer=Space(MAX_INI_BUFFERSIZE)
   lnSize=Len(lcDataBuffer)
   lnType=0

   lnResult=RegQueryString(lnRegHandle,tcEntry,0,@lnType,;
      @lcDataBuffer,@lnSize)

   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   If lnSize<2
      Return ""
   Endif

*** Return string based on length returned
   Return Substr(lcDataBuffer,1,lnSize-1)
   Endproc
* ReadRegistryString


************************************************************************
* Registry :: ReadRegistryInt
*********************************
*** Function: Reads an integer (DWORD) or short (4 byte or less) binary
*** value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to retrieve
*** Return: Registry String or .NULL. on error
************************************************************************
   Function ReadRegistryInt
   Lparameters tnHKey, tcSubkey, tcEntry
   Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)

   lnRegHandle=0

   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here's it's an INTEGER
   Declare Integer RegQueryValueEx ;
      IN Win32API As RegQueryInt;
      INTEGER nHKey,;
      STRING lpszValueName,;
      INTEGER dwReserved,;
      Integer @lpdwType,;
      INTEGER @lpbData,;
      INTEGER @lpcbData

   lnDataBuffer=0
   lnSize=4
   lnResult=RegQueryInt(lnRegHandle,tcEntry,0,@tnType,;
      @lnDataBuffer,@lnSize)
   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   Return lnDataBuffer
* EOP RegQueryInt


************************************************************************
* Registry :: WriteRegistryString
*********************************
*** Function: Reads a string value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
   Function WriteRegistryString
   Lparameters tnHKey, tcSubkey, tcEntry, tcValue, tlCreate
   Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)

   lnRegHandle=0

   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
      If !tlCreate
         Return .Null.
      Else
         lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
         If lnResult#ERROR_SUCCESS
            Return .Null.
         Endif
      Endif
   Endif

*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
   Declare Integer RegSetValueEx ;
      IN Win32API ;
      INTEGER nHKey,;
      STRING lpszEntry,;
      INTEGER dwReserved,;
      INTEGER fdwType,;
      STRING lpbData,;
      INTEGER cbData

*** Check for .NULL. which means delete key
   If !Isnull(tcValue)
*** Nope - write new value
      lnSize=Len(tcValue)
      lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_SZ,;
         tcValue,lnSize)
   Else
*** DELETE THE KEY
      lnResult=RegDeleteValue(lnRegHandle,tcEntry)
   Endif

   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   Return .T.
   Endproc
* WriteRegistryString

************************************************************************
* Registry :: WriteRegistryInt
*********************************
*** Function: Writes a numeric value to the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
   Function WriteRegistryInt
   Lparameters tnHKey, tcSubkey, tcEntry, tnValue,tlCreate
   Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)

   lnRegHandle=0

   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
      If !tlCreate
         Return .Null.
      Else
         lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
         If lnResult#ERROR_SUCCESS
            Return .Null.
         Endif
      Endif
   Endif

*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
   Declare Integer RegSetValueEx ;
      IN Win32API ;
      INTEGER nHKey,;
      STRING lpszEntry,;
      INTEGER dwReserved,;
      INTEGER fdwType,;
      INTEGER @lpbData,;
      INTEGER cbData

*** Check for .NULL. which means delete key
   If !Isnull(tnValue)
*** Nope - write new value
      lnSize=4
      lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_DWORD,;
         @tnValue,lnSize)
   Else
*** DELETE THE KEY
      lnResult=RegDeleteValue(lnRegHandle,tcEntry)
   Endif

   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   Return .T.
   Endproc
* WriteRegistryInt

************************************************************************
* Registry :: WriteRegistryBinary
*********************************
*** Function: Writes a binary value to the registry.
*** Binary must be written as character values:
*** chr(80)+chr(13) will result in "50 1D"
*** for example.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tnLength - you have to supply the length
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
   Function WriteRegistryBinary
   Lparameters tnHKey, tcSubkey, tcEntry, tcValue,tnLength,tlCreate
   Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
   tnLength=Iif(Type("tnLength")="N",tnLength,Len(tcValue))

   lnRegHandle=0

   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
      If !tlCreate
         Return .Null.
      Else
         lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
         If lnResult#ERROR_SUCCESS
            Return .Null.
         Endif
      Endif
   Endif

*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
   Declare Integer RegSetValueEx ;
      IN Win32API ;
      INTEGER nHKey,;
      STRING lpszEntry,;
      INTEGER dwReserved,;
      INTEGER fdwType,;
      STRING @lpbData,;
      INTEGER cbData

*** Check for .NULL. which means delete key
   If !Isnull(tcValue)
*** Nope - write new value
      lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_BINARY,;
         @tcValue,tnLength)
   Else
*** DELETE THE KEY
      lnResult=RegDeleteValue(lnRegHandle,tcEntry)
   Endif

   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   Return .T.
   Endproc
* WriteRegistryBinary

************************************************************************
* Registry :: DeleteRegistryKey
*********************************
*** Function: Deletes a registry key. Note this does not delete
*** an entry but the key (ie. a path node).
*** Use WriteRegistryString/Int with a .NULL. to
*** Delete an entry.
*** Pass: tnHKey - Registry Root node key
*** tcSubkey - Path to clip
*** Return: .T. or .NULL.
************************************************************************
   Function DeleteRegistryKey
   Lparameters tnHKey,tcSubkey
   Local lnResult, lnRegHandle

   tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)

   lnRegHandle=0

   lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
   If lnResult#ERROR_SUCCESS
*** Key doesn't exist or can't be opened
      Return .Null.
   Endif

   lnResult=RegDeleteKey(tnHKey,tcSubkey)

   =RegCloseKey(lnRegHandle)

   If lnResult#ERROR_SUCCESS
      Return .Null.
   Endif

   Return .T.
   Endproc
* DeleteRegistryKey

************************************************************************
* wwAPI :: EnumRegistryKey
*********************************
*** Function: Returns a registry key name based on an index
*** Allows enumeration of keys in a FOR loop. If key
*** is empty end of list is reached or the key doesn't
*** exist or is empty.
*** Pass: tnHKey - HKEY_ root key
*** tcSubkey - Subkey string
*** tnIndex - Index of key name to get (0 based)
*** Return: "" on error - Key name otherwise
************************************************************************
   Protected Procedure EnumKey
      Lparameters tnHKey, tcSubkey, tnIndex
      Local lcSubKey, lcReturn, lnResult, lcDataBuffer

      lnRegHandle=0

*** Open the registry key
      lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
      If lnResult#ERROR_SUCCESS
*** Not Found
         Return .Null.
      Endif

      Declare Integer RegEnumKey ;
         IN WIN32API ;
         INTEGER nHKey, ;
         INTEGER nIndex, ;
         STRING @cSubkey, ;
         INTEGER nSize

      lcDataBuffer=Space(MAX_INI_BUFFERSIZE)
      lnSize=MAX_INI_BUFFERSIZE
      lnReturn=RegEnumKey(lnRegHandle, tnIndex, @lcDataBuffer, lnSize)

      =RegCloseKey(lnRegHandle)

      If lnResult#ERROR_SUCCESS
*** Not Found
         Return .Null.
      Endif

      Return Trim(Chrtran(lcDataBuffer,Chr(0),""))
      Endfunc
* EnumRegistryKey

************************************************************************
* Registry :: EnumValue
*********************************
*** Function: Returns the name of a registry Value key. Note the actual
*** Value is not returned but just the key. This is done
*** so you can check the type first and use the appropriate
*** ReadRegistryX method. The type is returned by ref in the
*** last parameter.
*** Assume:
*** Pass: tnHKey - HKEY value
*** tcSubkey - The key to enumerate valuekeys for
*** tnIndex - Index of key to work on
*** @tnType - Used to pass back the type of the value
*** Return: String of ValueKey or .NULL.
************************************************************************
   Protected Function EnumValue
      Lparameters tnHKey, tcSubkey, tnIndex, tnType
      Local lcSubKey, lcReturn, lnResult, lcDataBuffer

      tnType=Iif(Type("tnType")="N",tnType,0)

      lnRegHandle=0

*** Open the registry key
      lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
      If lnResult#ERROR_SUCCESS
*** Not Found
         Return .Null.
      Endif

*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here it's STRING.
      Declare Integer RegEnumValue ;
         IN Win32API ;
         INTEGER nHKey,;
         INTEGER nIndex,;
         STRING @lpszValueName,;
         INTEGER @lpdwSize,;
         INTEGER dwReserved,;
         INTEGER @lpdwType,;
         STRING @lpbData,;
         INTEGER @lpcbData


      tcSubkey=Space(MAX_INI_BUFFERSIZE)
      tcValue=Space(MAX_INI_BUFFERSIZE)
      lnSize=MAX_INI_BUFFERSIZE
      lnValSize=MAX_INI_BUFFERSIZE

      lnReturn=RegEnumValue(lnRegHandle, tnIndex, @tcSubkey,@lnValSize, 0, @tnType, @tcValue, @lnSize)

      =RegCloseKey(lnRegHandle)

      If lnResult#ERROR_SUCCESS
*** Not Found
         Return .Null.
      Endif

      tcValue = Alltrim(Chrtran(tcValue , Chr(0), ""))    && memc 06/30/1999
      tcSubkey = Alltrim(Chrtran(tcSubkey, Chr(0), ""))

      If !Empty(tcValue) And Empty(tcSubkey)    && memc 06/30/1999
         tcSubkey = "0"
      Endif

      Return tcSubkey
      Endfunc
* EnumRegValue

************************************************************************
* Registry :: GetEnumValues
*********************************
*** Function: Retrieves all Values off a key into an array. The
*** array is 2D and consists of: Key Name, Value
*** Assume: Not tested with non-string values
*** Pass: @taValues - Result Array: Pass by Reference
*** tnHKEY - ROOT KEY value
*** tcSubKey - SubKey to work on
*** Return: Count of Values retrieved
************************************************************************
   Function GetEnumValues
   Lparameters taValues, tnHKey, tcSubkey
   Local x, lcKey

   lcKey="x"
   x=0
   Do While !Empty(lcKey) Or Isnull(lcKey)
      lnType=0
      lcKey=This.EnumValue(tnHKey,tcSubkey,x,@lnType)

      If Isnull(lcKey) Or Empty(lcKey)
         Exit
      Endif

      If lcKey = "0" && memc 06/30/1999
         lcKey = 0
      Endif

      x=x+1
      Dimension taValues[x,2]

      Do Case
      Case lnType=REG_SZ Or lnType=REG_BINARY Or lnType=REG_NONE
         lcValue=this.ReadRegistryString(tnHKey,tcSubkey,lcKey)
         If Type("lcKey") = "N"    && memc 06/30/1999
            lcKey = "0"
         Endif
         taValues[x,1]=lcKey
         taValues[x,2]=lcValue
      Case lnType=REG_DWORD
         lnValue=this.ReadRegistryInt(tnHKey,tcSubkey,lcKey)
         If Type("lcKey") = "N"    && memc 06/30/1999
            lcKey = "0"
         Endif
         taValues[x,1]=lcKey
         taValues[x,2]=lnValue
      Otherwise
         taValues[x,1]=lcKey
         taValues[x,2]=""
      Endcase
   Enddo

   Return x
   Endfunc
* GetEnumValues

************************************************************************
* Registry :: GetEnumKeys
*********************************
*** Function: Returns an array of all subkeys for a given key
*** NOTE: This function does not return Value Keys only
*** Tree Keys!!!!
*** Pass: @taKeys - An array that gets filled with key names
*** tnHKEY - Root Key
*** tcSubkey - Subkey to enumerate for
*** Return: Number of keys or 0
************************************************************************
   Function GetEnumKeys
   Lparameters taKeys, tnHKey, tcSubkey
   Local x, lcKey

   lcKey="x"
   x=0
   Do While !Empty(lcKey) Or Isnull(lcKey)
      lnType=0
      lcKey=This.EnumKey(tnHKey,tcSubkey,x)

      If Isnull(lcKey) Or Empty(lcKey)
         Exit
      Endif

      x=x+1
      Dimension taKeys[x]
      taKeys[x]=lcKey
   Enddo

   Return x
   Endfunc
* GetEnumKeys

   Function Release
   Release This
   Endfunc


Enddefine
*EOC Registry

_________________
利用>>搜尋<<的功能會比問的還要快得到答案.
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作