简体   繁体   中英

ODP.NET works in command shell but fails as a scheduled task (Windows Server 2012 R2)

Attempting to run a scheduled task that runs a PowerShell script using an Oracle.DataAccess.dll assembly throws the following error

New-Object : Exception calling ".ctor" with "0" argument(s): "The type initializer for 'Oracle.DataAccess.Client.OracleConnection' threw an exception."

Running the same action and arguments as the scheduled task in a PowerShell window as the same user works correctly.

I've tried loading the DLL using [System.Reflection.Assembly]::LoadFile , Add-Type -AssemblyName and Add-Type -Path

What differences are there between a scheduled task and a PowerShell window that could cause this?

I Met the problem much time. For me it comes from the fact that the Oracle DLL is not loaded (Paths and user may be different).

First : For a while now Oracle edited a full managed DLL for .NET which is available through Nugets . So I stop using the native odp.net that need Oracle package install. Now in each script I use :

# Download the package if it's not on the disk    
$version = '18.3.0'
try
{
  if (! $(Test-Path ".\NugetPackages\Oracle.ManagedDataAccess.$version\lib\net40\Oracle.ManagedDataAccess.dll"))
  {
    $ManagedDataAccess = Install-Package Oracle.ManagedDataAccess -Destination ".\NugetPackages" -Force -Source 'https://www.nuget.org/api/v2' -ProviderName NuGet -RequiredVersion $version -ErrorAction SilentlyContinue
  }
  Add-Type -Path ".\NugetPackages\Oracle.ManagedDataAccess.$version\lib\net40\Oracle.ManagedDataAccess.dll"
}
catch [System.Management.Automation.ParameterBindingException]
{
  $global:OracleError = New-Object PSCustomObject -Property @{"StackTrace"=$_.ScriptStackTrace;"Detail" = "Ligne $($_.InvocationInfo.ScriptLineNumber) : $($_.exception.message)";"TimeStamp"=([datetime]::Now)}
  $log = $null
}

# Connexion
$oraConn= New-Object Oracle.ManagedDataAccess.Client.OracleConnection (($compConStr)
$oraConn.Open()

# Requête SQL
$sql1 = @"
SELECT XX_MYSESSION_ID FROM XX_SILOGIXWSLOG 
  WHERE xx_name='customer_log'
  AND xx_param_4 IS NOT NULL
"@

$command1 = New-Object Oracle.ManagedDataAccess.Client.OracleCommand($sql1,$oraConn)

# Execution
$reader1=$command1.ExecuteReader()

$n = 0
while ($reader1.read())
{
  $reader1["XX_MYSESSION_ID"]  
}

# Close the conexion
$reader1.Close()
$oraConn.Close()

Second : I use the following snippet to discover the script directory, it works for normal and Scheduled Job (you can modify it for scheduled Task).

# Discover the Directory script
$scriptDirectory = $(Split-Path -parent $PSCommandPath)
if ($scriptDirectory -eq $null -or $scriptDirectory -eq "")
{
  $scriptDirectory = split-path -parent $((Get-ScheduledJob -Name 'RMAWarning').Command)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM