我们在C#中实现了一个Windows程序集。该程序监听套接字以接收传入的连接,并启动子进程(非托管的c代码),这些子进程应该使用此套接字。子进程由包含套接字句柄的参数的命令行启动。整个机制在.Net 4.8 Framework下运行良好,但在.Net 6下失败。以下是我们正在使用的代码摘录:
我们使用Sysinternals Process Explorer查看父进程和子进程的句柄。使用.Net 4.8,我们清楚地看到,在命令行中传递的套接字句柄在子进程的句柄列表中可用。然而,在.Net 6中传递的句柄却不可用。与.Net 4.8相比,.Net 6似乎继承的句柄较少。
为什么.Net 6在这个领域的行为不同?我们所做的所有研究/阅读都表明,“句柄继承”在.Net 6中仍应保持不变。
GetUserNameAndDomain(user, out var userName, out var domain);
var process = new Process{StartInfo = new ProcessStartInfo(command, arguments){UseShellExecute = false}};
WrapperImpersonationContext wrapperImpersonationContext = new WrapperImpersonationContext(domain, userName, password.ToUnsecureString(), false, false);
using (wrapperImpersonationContext) {
Action impersonationAction = () =>
{
process.Start();
};
wrapperImpersonationContext.Enter(impersonationAction);
}
这里的模拟身份主要是做类似于以下操作:
public WrapperImpersonationContext(string domain, string username, string password, bool automaticallyEnter = true, bool logonAsService = false) {
mDomain = domain;
mUsername = username;
mPassword = password;
mLogonType = logonAsService ? LOGON32_LOGON_SERVICE : LOGON32_LOGON_INTERACTIVE;
if (automaticallyEnter)
Enter();
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public void Enter(Action impersonationAction = null) {
//if (IsInContext)
// return;
mToken = new IntPtr(0);
try {
LogFactory.WriteVerbose("Logon to user '{0}' in domain '{1}'", mUsername, mDomain);
mToken = IntPtr.Zero;
bool logonSuccessfull = LogonUser(mUsername, mDomain, mPassword, mLogonType, LOGON32_PROVIDER_DEFAULT, ref mToken);
if (logonSuccessfull == false) {
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
WindowsIdentity identity = new WindowsIdentity(mToken);
WindowsIdentity.RunImpersonated(new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(mToken), impersonationAction);
LogFactory.WriteVerbose("Impersonation was successfully");
} catch (Exception exception) {
LogFactory.WriteWarning(exception);
throw;
}
}
我们使用Sysinternals Process Explorer查看父进程和子进程的句柄。使用.Net 4.8,我们清楚地看到,在命令行中传递的套接字句柄在子进程的句柄列表中可用。然而,在.Net 6中传递的句柄却不可用。与.Net 4.8相比,.Net 6似乎继承的句柄较少。
为什么.Net 6在这个领域的行为不同?我们所做的所有研究/阅读都表明,“句柄继承”在.Net 6中仍应保持不变。