mysql - 在 windows starpack 下包含 tdbc::mysql&tdbc::postgres 的 dll 的最佳方法是什么?

标签 mysql windows postgresql tcl tdbc

包 tdbc::mysql 和 tdbc::postgresql 需要 dll libmysql.dll 和 libpq.dll 在 PATH 中。将此 dll 包含到单个 starpack 中的最佳方法是什么?

现在我使用以下 pkgIndex.tcl:

if {[catch {package require Tcl 8.6}]} {
    return
}
package ifneeded tdbc::postgres 1.0.0 [list apply {{dir} {
  if { $::tcl_platform(os) eq "Windows NT" &&
        ($::tcl_platform(machine) eq "intel" || 
         $::tcl_platform(machine) ne "amd64") } {
    foreach n {libpq libeay32 ssleay32 comerr32 gssapi32 
               k5sprt32 krb5_32 libiconv-2 libintl-8} {     
      file copy -force [file join $dir ${n}.dll] \
        [file join $::env(WINDIR) System32 ${n}.dll]
    }
  }
  source [file join $dir tdbcpostgres.tcl]
  load [file join $dir tdbcpostgres100.dll] tdbcpostgres
}} $dir]

但这看起来很丑。

我试图找到一种方法将必要的库复制到解释器用来加载 dll 的临时文件夹中。但是通过查看Tcl源代码,发现临时目录的名称是不能用于脚本的。

更新:目前,我决定使用 twapi 来确定 Tcl 解释器使用的临时文件夹的名称。我得到以下代码:

if {[catch {package require Tcl 8.6}]} {
    return
}
package ifneeded tdbc::postgres 1.0.0 [list apply {{dir} {
  if { $::tcl_platform(os) eq "Windows NT" &&
        ($::tcl_platform(machine) eq "intel" || 
         $::tcl_platform(machine) eq "amd64") } {
    package require twapi
    set _ [file dirname [lindex [lsearch -inline -index 1 -glob \
          [twapi::get_process_modules [twapi::get_current_process_id] -path] \
          {*/twapi_base*.dll}] 1]]
    if { $_ eq "." } { 
      error "couldn't find temp folder name for tdbc::postgres support library" 
    }
    foreach fn [glob -types f -tails -directory $dir "*.dll"] {
      if { [string match -nocase "tdbcpostgres*" $fn] } continue
      file copy -force [file join $dir $fn] [file join $_ $fn]
    }
  } {
    set _ [pwd]
  }
  source [file join $dir tdbcpostgres.tcl]
  set tpwd [pwd]
  cd $_
  catch { load [file join $dir tdbcpostgres100.dll] tdbcpostgres } r o
  cd $tpwd
  return -options $o $r
}} $dir]

但是在程序退出后删除临时文件还是有问题。我只看到一个解决方案:在程序开始时扫描文件夹 $::env(TEMP) 并尝试删除所有名为 TCLXXXXXXXX 的临时文件夹。

最佳答案

如果没有管理员访问权限,将文件复制到 c:\windows\system32 的“解决方案”将无法工作,大多数从 Windows Vista 开始的应用程序都没有管理员访问权限。 (你必须选择“以管理员身份运行”)那么 system32 目录中的新文件呢?您只需更换它们。

一些备选方案:

  • 自己将所有 dll 复制到一个临时目录,切换到该目录并加载 dll(利用您在 . 以及在 Windows 上查看的事实):

    package ifneeded tdbc::postgres 1.0.0 [list apply {{dir} {
        set dest [file join $::env(TEMP) tcl[file seconds]]
        file mkdir $dest
        foreach dll [glob -dir $dir *.dll] {
            file copy $dll $dest
        }
        set cwd [pwd]
        cd $dest
        catch {
            source [file join $dir tdbcpostgres.tcl]
            load [file join $dest tdbcpostgres100.dll] tdbcpostgres
        } res opt
        cd $cwd
        return -options $opt $res
    }} $dir]
    

    但我们应该如何清理它呢?

  • 将 dll 编译到 starpack 中。这很难。

  • 自己编译扩展,因此它没有任何依赖性。我不知道该怎么做。
  • 自行加载每个所需的 dll。这是我最喜欢的解决方案,但它需要 twapi:

    package ifneeded tdbc::postgres 1.0.0 [list apply {{dir} {
        package require twapi
        foreach dll [glob -dir $dir *.dll] {
            ::twapi::load_library $dll
        }
        source [file join $dir tdbcpostgres.tcl]
        load [file join $dir tdbcpostgres100.dll] tdbcpostgres
    }} $dir]
    

关于mysql - 在 windows starpack 下包含 tdbc::mysql&tdbc::postgres 的 dll 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19612231/

相关文章:

java - 使用 Mysql 为 Java 应用程序进行数据库镜像

php - 使用两个 order by 的 codeigniter 事件记录查询

windows - 从任务计划程序运行批处理文件不适用于 java 命令

python - 在 Windows 上的本地主机上运行 Ansible-Playbook

postgresql - 为子表插入创建触发器会返回令人困惑的错误

sql - 根据给定的开放日期和关闭日期,生成一段时间内开放门票的计数

OS X EL Capitan 上的 MySQL 5.7.13 Homebrew : ERROR! 服务器在启动时退出而不更新 PID 文件

windows - 在 Windows 服务中实现 syslog 到远程主机

sql - R - Postgresql 将数据导出到 CSV

php - MySQL-第一行被跳过