使用模拟打开SQLconnection时发生TypeInitializationException

时间:2018-10-05 17:15:57

标签: c# exception impersonation sqlconnection

我在Windows窗体应用程序中使用TypeInitializationException时遇到问题,当使用模拟打开SQLconnection时(当模拟删除一切正常时),我不知道如何解决该问题。

这是StackTrace:

   v System.Data.SqlClient.SqlConnection..ctor()
   v System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Initialize(IDataServices dataServices, Object connection)
   v System.Data.Linq.DataContext.Init(Object connection, MappingSource mapping)
   v System.Data.Linq.DataContext..ctor(String fileOrServerOrConnection)
   v CallBackCvop.Persistance.UnitOfWork..ctor(String connectionString)
   v CallBackCvop.MainForm.RefreshOrders()
   v CallBackCvop.MainForm.BTN_Search_Click(Object sender, EventArgs e)
   v System.Windows.Forms.Control.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   v System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   v System.Windows.Forms.Control.WndProc(Message& m)
   v System.Windows.Forms.ButtonBase.WndProc(Message& m)
   v System.Windows.Forms.Button.WndProc(Message& m)
   v System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   v System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   v System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   v System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   v System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   v System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   v System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   v System.Windows.Forms.Application.Run(Form mainForm)
   v CallBackCvop.Program.Main()

这是innerException的StackTrace

   v System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName)
   v System.Configuration.ClientConfigPaths.SetNamesAndVersion(String applicationFilename, Assembly exeAssembly, Boolean isHttp)
   v System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
   v System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
   v System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record)
   v System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   v System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   v System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   v System.Data.SqlClient.SqlConnection..cctor()

这是我的模拟代码:

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class Impersonation : IDisposable
    {
        private readonly SafeTokenHandle _handle;
        private readonly WindowsImpersonationContext _context;

        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

        public Impersonation(string domain, string username, string password)
        {
            var ok = LogonUser(username, domain, password,
                           LOGON32_LOGON_NEW_CREDENTIALS, 0, out this._handle);
            if (!ok)
            {
                var errorCode = Marshal.GetLastWin32Error();
                throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode));
            }

            this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
        }

        public void Dispose()
        {
            this._context.Dispose();
            this._handle.Dispose();
        }

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

        public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
        {
            private SafeTokenHandle()
                : base(true) { }

            [DllImport("kernel32.dll")]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            [SuppressUnmanagedCodeSecurity]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool CloseHandle(IntPtr handle);

            protected override bool ReleaseHandle()
            {
                return CloseHandle(handle);
            }
        }
    }

问题是-我之前在不同的ap中使用了该模拟代码,并且一切正常。我很拼命,有帮助吗?谢谢。

这是连接字符串:

private readonly string _connectionString = "data source = xxx\\xxx; initial catalog = xxx; integrated security=True; MultipleActiveResultSets=True";

这里是开场白:

    using (UnitOfWork frt = new UnitOfWork(_connectionString))
    {
        _outCalls.DownloadOutCalls(frt, _orders.ReturnSetOfNumbers());
    }

UnitOfWork(您在这里获得TypeInitializationException):

 public class UnitOfWork : IDisposable
    {
        ....repositories...

        private readonly DataContext _context;


        public UnitOfWork(string connectionString)
        {
            _context = new DataContext(connectionString);


            ....repositories...
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_context != null)
                    _context.Dispose();
            }
        }
    }

内部异常是FileNotFoundException,但似乎引用了.exe本身-我不理解这一点。

编辑-2018年10月8日 我发现.exe在我的桌面上但不在共享Intranet驱动器上时,一切正常。但是模拟帐户具有与我的帐户相同的权利。 如前所述,我有一个使用相同模拟代码,相同连接字符串的其他应用程序,并且所有内容均可在我的台式机和共享驱动器上使用。

编辑-8.10.2018-11:00 所以它崩溃了... System.Diagnostics.FileVersionInfo.GetVersionInfo(pathToExe),

  • 我检查了模拟帐户的权限-一切正常,
  • 我没有假人和帐户就尝试了该应用-一切正常,
  • 我尝试通过模拟我的帐户使用该应用程序(应该可以)-无法运行

1 个答案:

答案 0 :(得分:0)

所以... 一段时间后,一个解决方案。 似乎在--- System.Diagnostics.FileVersionInfo.GetVersionInfo(pathToExe)中出现错误,因此将我的模拟调用从程序移到了工作单元。以此方式进行更改:

public class UnitOfWork : IDisposable
{
    public IOrderRepository Orders { get; }
    public ICallRepository OutCalls { get; }
    public ILoginRepository Login { get; }

    private readonly DataContext _context;


    public UnitOfWork(string connectionString)
    {
        _context = new DataContext(new SqlConnection());

        using (new Impersonation("domain", "user", "password"))
            _context.Connection.ConnectionString = connectionString;

        Orders = new OrderRepository(_context);
        OutCalls = new CallRepository(_context);
        Login = new LoginRepository(_context);
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_context != null)
                _context.Dispose();
        }
    }
}