我正在尝试使用 Golang 中的“ESENT.dll”库。目的是打开一个 ESEDB 文件并读取其中的一些数据。
根据 MSDN,我首先必须创建一个 ESE 会话,然后使用库中的以下函数附加 ESEDB 文件:
JET_ERR JET_API JetInit( JET_INSTANCE *pinstance);
JET_ERR JET_API JetBeginSession( JET_INSTANCE 实例, JET_SESID *psesid, const char *szUserName, 常量字符 *szPassword );
JET_ERR JET_API JetAttachDatabase( JET_SESID sesid, const char *sz文件名, JET_GRBIT grbit);
所以,这就是我尝试做的:
package main
import (
"fmt"
"os"
"syscall"
"unsafe"
)
var (
esentDLL = syscall.NewLazyDLL("ESENT.dll")
instance uintptr
sesid uintptr
)
func main() {
esedbFilePath, err := syscall.UTF16PtrFromString(".\\SRUDB.dat")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
} else {
fmt.Println("Done")
}
initEseSession()
attachEseDB(esedbFilePath)
}
func initEseSession() {
JetInit := esentDLL.NewProc("JetInit")
JetBeginSession := esentDLL.NewProc("JetBeginSession")
fmt.Print("JetInit call... ")
rInit, _, _ := JetInit.Call(
uintptr(unsafe.Pointer(&instance)))
if rInit != 0 {
fmt.Println("Error", rInit)
} else {
fmt.Println("Done")
}
fmt.Print("JetBeginSession call... ")
rBeginSession, _, _ := JetBeginSession.Call(
instance,
uintptr(unsafe.Pointer(&sesid)),
0,
0)
if rBeginSession != 0 {
fmt.Println("Error", rBeginSession)
} else {
fmt.Println("Done")
}
}
func attachEseDB(esedbFilePath *uint16) {
JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
fmt.Print("JetAttachDatabase call... ")
rAttachDatabase, _, _ := JetAttachDatabase.Call(
sesid,
uintptr(unsafe.Pointer(&esedbFilePath)),
0)
if rAttachDatabase != 0 {
fmt.Println("Error :", rAttachDatabase)
} else {
fmt.Println("Done")
}
}
但是,在 JetAttachDatabase 调用之后,我有一个未指定的错误。
JetInit call... Done
JetBeginSession call... Done
JetAttachDatabase call... Error : 4294965485
你能帮帮我吗? 谢谢
更新
我做了一些改变。 ESENT.dll 返回的错误代码是“长”类型。所以我将函数调用返回的 uintptr 转换为“int32”类型。
现在我得到了很好的错误代码。
另外,我发现 ESEDB 文件的绝对路径总是返回错误“No shuch file”。
这个问题用相对路径解决了。
但是现在,这就是我所拥有的:
Call JetCreateInstance... Done : Code 0 (The function succeeded)
Call JetInit... Done : Code 0 (The function succeeded)
Call JetBeginSession... Done : Code 0 (The function succeeded)
Call JetAttachDatabase... Error : Code -1032 (The file cannot be accessed because the file is locked or in use)
Call JetOpenDatabase... Error : Code -1203 (There is no such database)
Call JetGetDatabaseInfo... Error : Code -1010 (There is an invalid database ID)
Call JetCloseDatabase... Error : Code -1010 (There is an invalid database ID)
Call JetDetachDatabase... Error : Code -1203 (There is no such database)
Call JetEndSession... Done : Code 0 (The function succeeded)
Call JetTerm... Done : Code 0 (The function succeeded)
我用其他 ESEDB 文件(SRUDB.dat、spartan.edb、WebCacheV01.dat...)做了一些测试,但我总是遇到这个问题。
ESEDB 文件是在干净关机后从我自己的计算机和其他计算机上转储的,所以我不明白为什么我有这个问题...
根据可扩展存储引擎错误代码:
A JET_ERR 值为 zero 应被解释为成功。
A JET_ERR 值大于零 应被解释为警告。
A JET_ERR 值 小于零 应被解释为错误。
因此,错误码必须转换为有符号整数:
fmt.Println("Error :", int32(rAttachDatabase))
然后我们得到错误代码
-1811
,这意味着JET_errFileNotFound
(找不到文件。)
检查返回值不会多余
lastErr
:
func attachEseDB(esedbFilePath *uint16) {
JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
fmt.Print("JetAttachDatabase call... ")
rAttachDatabase, _, err := JetAttachDatabase.Call(
sesId,
uintptr(unsafe.Pointer(&esedbFilePath)),
0)
if err != nil {
fmt.Printf("%s ", err)
}
if rAttachDatabase != 0 {
fmt.Println("Error :", int32(rAttachDatabase))
} else {
fmt.Println("Done")
}
}
就我而言,结果是:
JetAttachDatabase call... The filename, directory name, or volume label syntax is incorrect. Error : -1811