从 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
最佳答案
当您从“C”程序执行它时,您可以清楚地看到它作为 32 位进程 (x86) 启动。由于您没有安装 32 位 OleDb 驱动程序,这就是当前的问题。您需要将“C”程序编译为 64 位 PE,然后它将作为 64 位进程启动 powershell。或者,使用以下路径显式执行 powershell:
c:\windows\sysnative\windowspowershell\v1.0\powershell.exe
这将强制 32 位“C”程序将 powershell 作为 64 位子进程启动。
关于c - 从 C 调用的 Powershell 脚本不会打开 OleDb 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16697821/