【问题标题】:Powershell script called from C does not open OleDb Connection从 C 调用的 Powershell 脚本未打开 OleDb 连接
【发布时间】:2013-05-17 20:41:35
【问题描述】:

C 函数调用Powershell 脚本时,我的数据库连接没有打开。但是,当我以运行 C 程序的用户身份登录服务器并从 DOS 提示符下启动它时,一切正常。

为什么C程序无法通过C打开数据库连接。

服务器是 Windows 2008 R2 64 位。

这是我正在运行的Powershell 脚本。它会为我创建一个调试日志来验证哪些部分正在工作。

$DEBUGStream = [System.IO.StreamWriter] "D:\powershell\DEBUG.txt"
$DEBUGStream.WriteLine("START DEBUG")

$ExcelFile = "D:\InterfaceData\excel\" + $args[0]
$Sheetname = "Sheet2$"
$OleDbConn = New-Object “System.Data.OleDb.OleDbConnection”
$OleDbCmd = New-Object “System.Data.OleDb.OleDbCommand”
$OleDbAdapter = New-Object “System.Data.OleDb.OleDbDataAdapter”
$DataTable = New-Object “System.Data.DataTable”

$OleDbConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=`"$ExcelFile`";Extended Properties=`"Excel 12.0 Xml;HDR=YES`";"
$OleDbConn.Open()

$DEBUGStream.WriteLine("Connection: $OleDbConn.State")
    $DEBUGStream.WriteLine("Environment: $env:Processor_Architecture")

$OleDbCmd.Connection = $OleDbConn
$OleDbCmd.commandtext = “Select * from [$Sheetname]”
$OleDbAdapter.SelectCommand = $OleDbCmd

$RowsReturned = $OleDbAdapter.Fill($DataTable)
$DEBUGStream.WriteLine("Data Table fill: Rows: $RowsReturned")
$intRow = 1
ForEach ($DataRec in $DataTable) {
    $DEBUGStream.WriteLine("DATA TABLE ROW $intRow")
    $intRow++
}

$DEBUGStream.WriteLine("Loop finished")

$OleDbConn.Close()

$DEBUGStream.WriteLine("All Closed")
$DEBUGStream.close()

这是我在 DOS 提示符下手动运行时的输出

C:\Users\me>powershell -executionpolicy bypass d:\powershell\Interface.ps1 test.xlsx
START DEBUG
Connection: Open
    Environment: AMD64
Data Table fill: Rows: 4
DATA TABLE ROW 1
DATA TABLE ROW 2
DATA TABLE ROW 3
DATA TABLE ROW 4
Loop finished
All Closed

这是从C 程序调用时的输出。我使用system 命令调用它。

START DEBUG
Connection: Closed
    Environment: x86
Data Table fill: Rows: 
Loop finished
All Closed

编辑

如果我运行 64 位 Powershell 版本并从命令提示符运行脚本,我会收到一个新错误。我已经安装了 64 位版本的 Microsoft Access Database Engine 2010 (14.0.4763.1000):

C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass d:\wcc_powershell\WRIRMPTruckInterface.ps1 test.xlsx

C:\Users\me>C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass d:\powershell\Interface.ps1 
Exception calling "Open" with "0" argument(s): "The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine."
At D:\powershell\Interface.ps1:19 char:16
+ $OleDbConn.Open <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

【问题讨论】:

  • 没有 DOS 提示符 - DOS 已经死了十多年了。 2K8R2 中有 2 种可能的命令行环境 - CMD 和 PowerShell。你用的是哪个?
  • @alroc - 当我在服务器上直接从 Powershell 运行它时,我打开命令提示符并运行命令 powershell -executionpolicy bypass d:\powershell\Interface.ps1 test.xlsx

标签: c powershell oledb powershell-2.0 windows-server-2008-r2


【解决方案1】:

当您从“C”程序执行它时,您可以清楚地看到它作为 32 位进程 (x86) 启动。由于您没有安装 32 位 OleDb 驱动程序,这就是手头的问题。您需要将“C”程序编译为 64 位 PE,然后它将作为 64 位进程启动 powershell。或者,使用以下路径显式执行 powershell:

c:\windows\sysnative\windowspowershell\v1.0\powershell.exe

这将强制 32 位“C”程序将 powershell 作为 64 位子进程启动。

这是我的一篇相关博文:http://www.nivot.org/blog/post/2012/12/18/Ensuring-a-PowerShell-script-will-always-run-in-a-64-bit-shell

【讨论】:

  • 完全正确!我发现 this blog entry 关于强制 powershell 检测它是否在 64 位架构上运行 32 位 powershell。所以脚本会在正确的进程中自动运行。
  • 我更新了答案,并附上了我最近关于该主题的博客文章的链接。
猜你喜欢
  • 2019-12-27
  • 1970-01-01
  • 2015-09-07
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
相关资源
最近更新 更多