Damien 一针见血,问题是当您运行控制台应用程序时,您是在以您的身份运行它,它可以访问 UNC。当服务运行您的控制台应用程序时,它以您绑定到该服务的用户身份运行它。你有几个选择:
- 1:将服务设置为以有权访问 UNC 的用户身份运行
- 2:使用 Impersonation 以您想要的用户身份进行连接。
无论如何,从控制台应用程序而不是您的服务运行它是没有用的。
我已经包含了一个我创建的让模拟变得容易的类:
Imports System.Security.Principal
Imports System.Runtime.InteropServices
''' <summary>
''' Used to temporarily impersonate another user
''' Must use a USING block or dispose of instance to undo impersonation
''' </summary>
''' <remarks></remarks>
Public Class ImpersonateFNS
Implements IDisposable
Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Integer
Private _impersonatedUser As WindowsImpersonationContext = Nothing
Private _loggedOn As Boolean = False
''' <summary>
''' Should call this in a USING block OR, make sure you dispose this object when done impersonating
''' </summary>
Public Sub New(ByVal Domain As String, ByVal UserName As String, ByVal Password As String)
Dim token As IntPtr = IntPtr.Zero
'If (LogonUserA(UserName, Domain, Password, 2, 0, token) <> 0) Then
If (LogonUserA(UserName, Domain, Password, 9, 0, token) <> 0) Then
_loggedOn = True
Dim newIdentity As WindowsIdentity = New WindowsIdentity(token)
_impersonatedUser = newIdentity.Impersonate()
Else
Dim ret As Integer = Marshal.GetLastWin32Error()
'Console.WriteLine("LogonUser failed with error code : {0}", ret)
'Throw New System.ComponentModel.Win32Exception(String.Format("LogonUser failed with error code : {0}", ret))
Throw New Security.SecurityException(String.Format("LogonUser failed with error code : {0}", ret))
End If
End Sub
Private ReadOnly Property LoggedOn As Boolean
Get
Return _loggedOn
End Get
End Property
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
If _impersonatedUser IsNot Nothing Then
_impersonatedUser.Undo()
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
如上所示创建类,然后调用位于 USING 块中,这样当您完成业务时,它将撤消模拟。像这样:
Using x as New ImpersonationFNF("MyDomain", "User","Password")
'Copy, read, whatever the stuff you need to do here
End Using