Powershell脚本引发的异常无法被脚本或csharp调用者捕获

时间:2018-06-27 20:51:21

标签: c# sql-server powershell exception

我正在编写一个c-sharp函数来执行powershell脚本并获取执行结果。我正在使用它到severla数据库类型的数据库连接。我为mysql和postgres编写了Powershell脚本,并且可以工作,但是当我为sqlserver编写脚本时,如果数据库服务中断,则无法在打开连接期间捕获异常,请不要通过脚本(即使我放置try / catch)也不能通过c-尖锐的呼叫者尝试/抓住。

[更新]:如果我通过主应用程序线程运行Function,它将运行异常并完成操作,而如果我由主应用程序的子线程运行,则不会运行,并且挂起并保持运行异常。

你能帮我吗?

谢谢

用于运行Powershell脚本的csharp代码下面

public static bool RunPowershellScript(string scriptFile, List<string> parameters, out ReturnInfo scriptresult)

{
bool retval = false;

            scriptresult = new ReturnInfo();

            RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

            using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
            {
                try
                {
                    runspace.Open();
                    RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
                    Pipeline pipeline = runspace.CreatePipeline();
                    pipeline.Commands.AddScript("Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force");

                    Collection<PSObject> psObjects;

                    psObjects = pipeline.Invoke();

                    pipeline = null;

                    pipeline = runspace.CreatePipeline();
                    Command scriptCommand = new Command(scriptFile);
                    Collection<CommandParameter> commandParameters = new Collection<CommandParameter>();
                    foreach (string scriptParameter in parameters)
                    {
                        CommandParameter commandParm = new CommandParameter(null, scriptParameter);
                        commandParameters.Add(commandParm);
                        scriptCommand.Parameters.Add(commandParm);
                    }
                    pipeline.Commands.Add(scriptCommand);
                    psObjects = pipeline.Invoke();
                    scriptresult = new ReturnInfo();

                    foreach (PSObject p in psObjects)
                    {
                        if (p.BaseObject is Hashtable)
                        {

                            Hashtable ht = p.ImmediateBaseObject as Hashtable;
                            scriptresult.ReturnCode = (int)ht["ReturnCode"];
                            scriptresult.ReturnNotificationMessage = (string)ht["ReturnNotificationMessage"];
                            scriptresult.ReturnNotificationTitle = (string)ht["ReturnNotificationTitle"];

                            Console.WriteLine(scriptresult.ReturnCode);
                            Console.WriteLine(scriptresult.ReturnNotificationMessage);
                            Console.WriteLine(scriptresult.ReturnNotificationTitle);

                            break;
                        }
                    }
                    retval = true;
                }
                catch (Exception exc)
                {
                    string logMessage = String.Format("[{0} Plugin] RunPowershellScript fail. Error: {1}", Runclass.PluginLogName, exc.ToString());
                    LogMain.Error(logMessage);
                    LogPlugin.Error(logMessage);

                    scriptresult.ReturnCode = -128;
                    scriptresult.ReturnNotificationMessage = string.Format("Esecuzione dello script non corretta a causa di un errore.\nMessaggio: {0}", exc.Message);
                    scriptresult.ReturnNotificationTitle = "Errore esecuzione dello script";
                }
            }

            return retval;
        }

及以下Powershell脚本

Param(
    [string]$username,
    [string]$password,
    [string]$database,
    [string]$hostname,
    [string]$Query,
    [switch]$IntegratedSecurity,
    [int]$QueryTimeout = 10
  )

#$MySQLAdminUserName = $username
#$MySQLAdminPassword = $password
#$MySQLDatabase = $database
#$MySQLHost = $hostname

$ConnectionString="";

if (-not ($IntegratedSecurity))
{   
    $ConnectionString = "Server=$hostname;Database=$database;user id=$username;password=$password;Connect Timeout=$QueryTimeout;"
}
Else
{   
    $ConnectionString = "Server=$hostname;Database=$database;Integrated Security=SSPI;Connect Timeout=$QueryTimeout;"
}

Write-Host "CONN STRING: $ConnectionString"

[hashtable]$Return = @{} 
$Return.ReturnCode = [int]-1000
$Return.ReturnNotificationMessage = [string]"" 
$Return.ReturnNotificationTitle = [string] ""

$_currentstate = 0

Try {

    #$scriptPath = split-path -parent $PSCommandPath
    #$scriptSupportPath = $scriptPath + "\Components"
    #$assemblytobeloaded = $scriptSupportPath+"\MySql.Data.dll";

    #[void][system.reflection.Assembly]::LoadFrom($assemblytobeloaded)
    #[system.reflection.Assembly]::loadwithpartialname('System.Data')

    $Connection = New-Object System.Data.SqlClient.SqlConnection
    $_currentstate = 1
    $Connection.ConnectionString = $ConnectionString

    $_currentstate = 2
    $cmd = New-Object System.Data.SqlClient.SqlCommand  
    $cmd.Connection = $Connection
    $cmd.CommandText  = $Query
    $cmd.CommandTimeout = 0

    $Connection.Open()

    $cmd.ExecuteNonQuery()

    $Connection.Dispose()
    $cmd.Dispose()

    $_currentstate = 3
    $Return.ReturnCode = [int]0
    $Return.ReturnNotificationMessage = [string]"Script success" 
    $Return.ReturnNotificationTitle = [string] "Interrogazione SQL Server riuscita"

    $_currentstate = 4
}
catch [System.Data.SqlClient.SqlException]
{
    $ReturnCode=-1000000
    switch($_currentstate)
    {
        0 { $ReturnCode=-1000001    }   # impossible loading Assembly System.Data.SQLData
        1 { $ReturnCode=-1000100    }   # impossible open connection
        2 { $ReturnCode=-1000200    }   # impossible execute query 
    }
    Write-Host  $ReturnCode

    $Return.ReturnCode = [int]$ReturnCode
    $Return.ReturnNotificationMessage =[string]"Script failed: " + $PSItem.ToString()
    $Return.ReturnNotificationTitle = [string] "Errore interrogazione MySQL"
}
Catch {
#    Write-Host "ERROR : Unable to run query : [ $query ]. Error: " + $PSItem.ToString()

    $ReturnCode=-1000000
    switch($_currentstate)
    {
        0 { $ReturnCode=-1000001    }   # impossible loading Assembly System.Data.SQLData
        1 { $ReturnCode=-1000100    }   # impossible open connection
        2 { $ReturnCode=-1000200    }   # impossible execute query 
    }
    Write-Host  $ReturnCode

    $Return.ReturnCode = [int]$ReturnCode
    $Return.ReturnNotificationMessage =[string]"Script failed: " + $PSItem.ToString()
    $Return.ReturnNotificationTitle = [string] "Errore interrogazione MySQL"
}
Finally 
{
    if($Connection) 
    {
        $Connection.Close()
    }
}

Return $Return

0 个答案:

没有答案