(雖然不建議使用Office互操作在服務器上,但有時我們不得不...)
問題是關係到安全性。 ASP.NET進程的用戶身份沒有使用Office應用程序的訪問權限,並且身份應該只具有運行應用程序所需的最低權限。您可以使用代碼模擬在運行時提高權限,而無需在web.config中設置模擬或爲我的ASP.NET用戶帳戶使用高特權帳戶。我已經在服務器上使用它,我喜歡這種方法。
您可以通過google瞭解更多。 下面是從http://support.microsoft.com/kb/306158的代碼:
public class CodeImpersonate
{
/// <summary>
/// This logon type is intended for users who will be interactively using the computer, such as a user being logged on by a terminal server,
/// remote shell, or similar process. This logon type has the additional expense of caching logon information for disconnected operations; therefore,
/// it is inappropriate for some client/server applications, such as a mail server.
/// </summary>
public const int LOGON32_LOGON_INTERACTIVE = 2;
/// <summary>
/// Use the standard logon provider for the system. The default security provider is negotiate,
/// unless you pass NULL for the domain name and the user name is not in UPN format. In this case, the default provider is NTLM.
/// Windows 2000: The default security provider is NTLM.
/// </summary>
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
public bool ImpersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void UndoImpersonation()
{
if (impersonationContext != null)
impersonationContext.Undo();
}
}
複製一個文件中的上述代碼。下面是一個示例使用它:
CodeImpersonate codeImpersonate = null;
try
{
codeImpersonate = new CodeImpersonate();
var isLoggedIn = codeImpersonate.ImpersonateValidUser(AppConfigs.OfficeUser, AppConfigs.OfficeUeerDomnia, AppConfigs.OfficeUserPass);
if (isLoggedIn)
{
//Do your office work....
}
else
throw new InvalidOperationException("Login failed for office user.");
}
finally
{
if (codeImpersonate != null)
codeImpersonate.UndoImpersonation();
codeImpersonate = null;
}
要在幾個地方使用上面的代碼,這裏是一個門面:
public class ImpersonateServices
{
public ImpersonateServices(String userName, String domain, String password)
{
this.UserName = userName;
this.Domain = domain;
this.Password = password;
}
public string UserName { get; private set; }
public string Domain { get; private set; }
public string Password { get; private set; }
public void Execute(Action privilegedAction)
{
CodeImpersonate codeImpersonate = null;
try
{
codeImpersonate = new CodeImpersonate();
var isLoggedIn = codeImpersonate.ImpersonateValidUser(this.UserName, this.Domain, this.Password);
if (isLoggedIn){
privilegedAction();
}
else
throw new InvalidOperationException("Login failed for office user.");
}
finally
{
if (codeImpersonate != null)
codeImpersonate.UndoImpersonation();
codeImpersonate = null;
}
}
}
使用它像:
var impersonateServices = new ImpersonateServices(AppConfigs.OfficeUser,
AppConfigs.OfficeUserDomain,
AppConfigs.OfficeUserPass);
impersonateServices.Execute(() => {
//Do your Office work...
});
的辦公室 - 用戶應該是有效的本地或域帳戶。 要測試辦公用戶帳戶的工作情況,請使用此用戶帳戶憑證登錄到服務器並啓動MS Word應用程序。如果第一次打開Word,可能會出現一些與彈出窗口相關的設置。解決它們,否則它們可能在編程訪問期間產生問題。
如果您將用戶帳戶憑證保留在配置文件中,請考慮加密值。請參見下面的SO Q &答:
How to encrypt one entry in web.config
Encrypting appSettings in web.config
希望這有助於...
咦?您的服務器是否安裝了Word? – KingCronus 2012-04-11 14:26:57
從客戶端檢查服務,可能是訪問權限問題 – Likurg 2012-04-11 14:29:53
您不應將Office interop庫用於服務器應用程序。它違反了微軟的建議,因爲可能會有僵局和其他不愉快的事情,會完全阻礙你的應用程序。 – Leonard 2012-04-11 14:31:50