首页 > 解决方案 > 从 Windows 服务上的模拟用户访问打印机

问题描述

我正在开发用于在不同凭据下下载和打印文档(pdf、excel.word)的 Windows 服务(需要在不同用户下的打印队列中添加文档)。当我模拟用户时,我得到一个例外“打印机设置无效”。当我在自己的上下文中运行服务时,没有异常并且它按预期工作

这是windows服务配置:

var exitCode = HostFactory.Run(x =>
{
    x.Service<PrinterCentralPointService>(service =>
    {
        service.ConstructUsing(printerService => new PrinterCentralPointService());
        service.WhenStarted(printerService => printerService.Start());
        service.WhenStopped(printerService => printerService.Stop());
    });
    x.RunAsLocalSystem();
});
int exitCodeValue = (int)Convert.ChangeType(exitCode, exitCode.GetTypeCode());
Environment.ExitCode = exitCodeValue;

服务:

public class PrinterCentralPointService {
    private readonly Timer _timer;
    public PrinterCentralPointService() {
        _timer = new Timer(1000) { AutoReset = false };
        _timer.Elapsed += TimerElapsed;
    }
    private void TimerElapsed(object sender, ElapsedEventArgs e)
    {
        var ps = new PrinterSettings(); // works fine
        using (var i = new ImpersonatedUser("login", "domain", "password"))
        {
            var ps = new PrinterSettings(); // default printer is not defined and etc...      // ... aspose code to send to printer
        }
    }
    public void Start() {
        _timer.Start();
    }
    public void Stop() {
        _timer.Stop();
    }
}

和 ImpersonatedUser.cs

public class ImpersonatedUser: IDisposable 
{
    IntPtr userHandle;
    WindowsImpersonationContext impersonationContext;
    public ImpersonatedUser(string user, string domain, string password) 
    {
        userHandle = IntPtr.Zero;
        bool loggedOn = LogonUser(
            user,
            domain,
            password,
            LogonType.Batch,
            LogonProvider.Default,
            out userHandle);
        if (!loggedOn)
            throw new Win32Exception(Marshal.GetLastWin32Error());
        impersonationContext = WindowsIdentity.Impersonate(userHandle);
    }
    public void Dispose() 
    {
        if (userHandle != IntPtr.Zero) 
        {
            CloseHandle(userHandle);
            userHandle = IntPtr.Zero;
            impersonationContext.Undo();
            logger.Debug("Finished Impersonating user");
        }
    }
    [DllImport("advapi32.dll", SetLastError = true)]
    static extern bool LogonUser(
        string lpszUsername,
        string lpszDomain,
        string lpszPassword,
        LogonType dwLogonType,
        LogonProvider dwLogonProvider,
        out IntPtr phToken
    );
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hHandle);
    enum LogonType: int 
    {
        Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            NetworkCleartext = 8,
            NewCredentials = 9,
    }
    enum LogonProvider: int 
    {
        Default = 0,
    }
}

我究竟做错了什么?

标签: c#windows-servicesasposetopshelf

解决方案


推荐阅读