gpt4 book ai didi

c# - 从 Windows 服务打印时,CreateProcessAsUser 不使用 LogonUser token

转载 作者:行者123 更新时间:2023-11-30 17:31:05 25 4
gpt4 key购买 nike

我正在本地系统帐户下构建一个 Windows 服务,它将在某个时间间隔内打印 pdf。

为此,我使用 LogonUser

创建用户 token
IntPtr currentToken = IntPtr.Zero;
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_PROVIDER_DEFAULT = 0;
bool loggedOn = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref currentToken);

并在 CreateProcessAsUser 中传递此 currentToken

CreateProcessAsUser(primaryToken, null, command, ref Security1, ref Security2, false, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, lpEnvironment, null, ref StartupInfo, out processInfo_);

但它没有做它的工作

如果我使用以下代码获取当前用户 token 。

public static IntPtr GetCurrentUserToken()
{
IntPtr currentToken = IntPtr.Zero;
IntPtr primaryToken = IntPtr.Zero;
IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;

int dwSessionId = 0;
IntPtr hUserToken = IntPtr.Zero;
IntPtr hTokenDup = IntPtr.Zero;

IntPtr pSessionInfo = IntPtr.Zero;
int dwCount = 0;

WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref dwCount);

Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));

Int32 current = (int)pSessionInfo;
for (int i = 0; i < dwCount; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
if (WTS_CONNECTSTATE_CLASS.WTSActive == si.State)
{
dwSessionId = si.SessionID;
break;
}

current += dataSize;
}

WTSFreeMemory(pSessionInfo);

bool bRet = WTSQueryUserToken(dwSessionId, out currentToken);
if (bRet == false)
{
return IntPtr.Zero;
}

bRet = DuplicateTokenEx(currentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out primaryToken);
if (bRet == false)
{
return IntPtr.Zero;
}

return primaryToken;
}

然后 CreateProcessAsUser 工作正常。但我需要通过 LogonUser 创建 token ,因为在用户注销后GetCurrentUserToken` 方法不返回用户 token ,我也希望在注销后获得用户 token 。

更新我在像这样调用 CreateProcessAsUser 之后检查最后一个错误

uint exitCode; 

if (!GetExitCodeProcess(processInfo_.hProcess, out exitCode))
{
int lastError = Marshal.GetLastWin32Error();
Logger.LogService(" GetExitCodeProcess Error " + lastError);
}

但是 GetExitCodeProcess 返回 true。我没有发现任何错误

最佳答案

首先

与您上次发布此问题 (Print Pdf from windows service and keep working after logoff) 一样,您需要了解并解决特定 API 调用失败的问题,然后调用 GetLastError这将为您提供有关调用失败原因的更多信息

GetLastError : Retrieves the calling thread's last-error code value

其次

可能是 GetCurrentUserToken 中的调用之一,例如 WTSQueryUserToken 可能只是存在权限问题或其他可以修复的问题(尽管我对此表示怀疑)

阅读 WTSQueryUserToken 的文档它似乎说明了以下内容

WTSQueryUserToken : Obtains the primary access token of the logged-on user specified by the session ID.

此外,WTSQueryUserToken 可能会返回

ERROR_NO_TOKEN
1008

ERROR_NO_TOKEN : The token query is for a session in which no user is logged-on. This occurs, for example, when the session is in the idle state or SessionId is zero.

第三

在我看来,我认为这种方法永远不会适用于您的情况,实际上官方不推荐从服务打印。

类似问题请看吹

Printing from a Windows Service

Printing from a .NET Service

最后

我唯一能想到的就是在可以访问打印机的用户帐户下运行您的服务,或者通过调用 LogonUser 来模拟用户, LoadUserProfile , 和 ImpersonateLoggedOnUser然后通过 Gdi+ 打印(这将有其自身的问题)

请注意

While it is possible to send GDI+ output to a printer by obtaining a device context handle for the printer and then passing that handle to a GDI+ Graphics constructor, this is not recommended. The GDI+ functions and classes are not supported for use within a Windows service. Attempting to use these functions and classes from a Windows service may produce unexpected problems, such as diminished service performance and run-time exceptions or errors:


简而言之,您目前的解决方案和您当前拥有的源代码不太可能工作,而且在我看来,您很可能会在这个问题上花费大量时间来尝试做一些服务确实没有设计的事情做(这也不在当前问题的范围内)。

我真的认为你需要认真地重新考虑你正在尝试做什么以及为什么,祝你好运

有关 GDI 打印和从服务打印的其他信息

How to install printer which should be accessible from windows service?

Printing from a Windows Service

关于c# - 从 Windows 服务打印时,CreateProcessAsUser 不使用 LogonUser token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48494988/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com