SQLCLR似乎无法启动Windows应用程序

时间:2019-10-11 06:31:30

标签: c# .net sql-server desktop-application sqlclr

我正在尝试使用SQLCLR从SQL Server启动Windows程序。调用的过程没有错误,但是程序似乎没有启动。

有什么主意我可能做错了吗?

这是该过程的.NET代码:

using System;
using Microsoft.SqlServer.Server;
using System.Diagnostics;

namespace MyUtility
{
    public class StoredProcedures
    {
        [Microsoft.SqlServer.Server.SqlProcedure]
        public static void MyUtilityExecute()
        {
            string result;

            try
            {
                Process myProcess = new Process();
                myProcess.StartInfo.FileName = "C:\\Windows\\System32\\notepad.exe";
                myProcess.StartInfo.UseShellExecute = false;
                myProcess.StartInfo.CreateNoWindow = false;
                myProcess.Start();

                result = "Success! Time = "
                        + DateTime.Now.ToString("dddd, dd MMMM yyyy HH:mm:ss");
                SqlContext.Pipe.Send(result);
            }
            catch
            {
                result = "There was an error!";
                SqlContext.Pipe.Send(result);
            }
        }
    }
}

这是我的T-SQL代码,用于创建程序集和包装器对象:

USE [MyDatabase]
GO

CREATE ASSEMBLY MyUtility
AUTHORIZATION [dbo]
FROM 'C:\MyPath\MyUtility\bin\Debug\MyUtility.dll'
WITH PERMISSION_SET = UNSAFE
GO

CREATE PROCEDURE usp_MyUtilityExecute
AS EXTERNAL NAME 
    MyUtility.[MyUtility.StoredProcedures].MyUtilityExecute
GO

EXECUTE usp_MyUtilityExecute;

1 个答案:

答案 0 :(得分:3)

您是否检查了任务管理器,进程管理器或查看本地进程的任何其他方式来确定程序是否真正启动?我敢打赌。问题在于,SQL Server是与(Windows)用户会话完全独立的后台进程,并且无法访问您的桌面(即使SQL Server在您登录的同一台计算机上运行,​​并且实际上经常在运行)在您仅向其发送请求的另一台计算机上,就像网站的远程方式一样。查看GUI应用程序或窗口的唯一方法是,如果您使用的是SQL Server Express LocalDB,因为这是一个用户模式进程,在您的会话中作为后台进程运行,并且它确实可以访问您的桌面。因此,记事本应该正在运行,只是看不到它。而且,如果继续执行此存储过程,则每次可能会生成一个新的单独的记事本进程。您可能想杀死那些;-)。

如果要测试以查看SQL Server是否真的可以生成基于OS的进程/应用程序,只需在.cmd中创建一个简单的C:\temp脚本,即可执行以下操作:

ECHO %TIME% >> C:\TEMP\_SQLCLR_test.txt

然后将第一行StartInfo更改为:

myProcess.StartInfo.FileName = @"C:\TEMP\_SQLCLR_test.cmd";

也许还有:

myProcess.StartInfo.CreateNoWindow = true;

这将测试整个概念,而无需UI交互(假设运行SQL Server进程的登录帐户有权访问和写入/修改 C:\ TEMP 目录)。 / p>

!重要提示!!

Process是一次性对象,因此需要在using()构造中创建,或者您需要实现try / finally来管理它,并调用{ {1}},无论发生什么情况。在当前设置中,如果有异常,您将拥有一个孤立的外部资源,该资源将一直保留在内存/文件系统句柄/等中,直到垃圾被收集为止,并且不确定何时会发生这种情况,因为我不认为SQL Server会调用经常。

相关问题