Windows 2004 更新后无法以其他用户身份运行 EXCEL.EXE
Posted
技术标签:
【中文标题】Windows 2004 更新后无法以其他用户身份运行 EXCEL.EXE【英文标题】:Can not run EXCEL.EXE as other user after Windows 2004 update 【发布时间】:2021-01-11 02:45:47 【问题描述】:我需要使用不同于当前用户的用户运行 EXCEL.EXE;过去我这样做没有任何问题,但在将系统更新到 Windows 10 Pro 版本 2004 (19041.508) 后,此方法不再有效。
我正在使用以下课程(感谢Impersonate user in Windows Service):
public class CreateProcess
#region Constants
const UInt32 INFINITE = 0xFFFFFFFF;
const UInt32 WAIT_FAILED = 0xFFFFFFFF;
#endregion
#region ENUMS
[Flags]
public enum LogonType
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
LOGON32_LOGON_NEW_CREDENTIALS = 9
[Flags]
public enum LogonProvider
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT35,
LOGON32_PROVIDER_WINNT40,
LOGON32_PROVIDER_WINNT50
#endregion
#region Structs
[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
public Int32 cb;
public String lpReserved;
public String lpDesktop;
public String lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
public IntPtr hProcess;
public IntPtr hThread;
public Int32 dwProcessId;
public Int32 dwThreadId;
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
public int nLength;
public unsafe byte* lpSecurityDescriptor;
public int bInheritHandle;
public enum TOKEN_TYPE
TokenPrimary = 1,
TokenImpersonation
public enum SECURITY_IMPERSONATION_LEVEL
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
#endregion
#region FUNCTIONS (P/INVOKE)
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool RevertToSelf();
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean LogonUser
(
String UserName,
String Domain,
String Password,
LogonType dwLogonType,
LogonProvider dwLogonProvider,
out IntPtr phToken
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CreateProcessAsUser
(
IntPtr hToken,
String lpApplicationName,
String lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
Boolean bInheritHandles,
Int32 dwCreationFlags,
IntPtr lpEnvironment,
String lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject
(
IntPtr hHandle,
UInt32 dwMilliseconds
);
[DllImport("kernel32", SetLastError = true)]
public static extern Boolean CloseHandle(IntPtr handle);
#endregion
#region Functions
public static int LaunchCommand(string command, string domain, string account, string password)
int ProcessId = -1;
PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();
STARTUPINFO startInfo = new STARTUPINFO();
Boolean bResult = false;
UInt32 uiResultWait = WAIT_FAILED;
var token = ValidateParametersAndGetFirstLoginToken(domain, account, password);
var duplicateToken = IntPtr.Zero;
try
startInfo.cb = Marshal.SizeOf(startInfo);
startInfo.lpDesktop = "winsta0\\default";
bResult = CreateProcessAsUser(
token,
null,
command,
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
null,
ref startInfo,
out processInfo
);
if (!bResult) throw new Exception("CreateProcessAsUser error #" + Marshal.GetLastWin32Error());
// Wait for process to end
uiResultWait = WaitForSingleObject(processInfo.hProcess, INFINITE);
ProcessId = processInfo.dwProcessId;
if (uiResultWait == WAIT_FAILED) throw new Exception("WaitForSingleObject error #" + Marshal.GetLastWin32Error());
finally
if (token != IntPtr.Zero)
CloseHandle(token);
if (duplicateToken != IntPtr.Zero)
CloseHandle(duplicateToken);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return ProcessId;
private static IntPtr ValidateParametersAndGetFirstLoginToken(string domain, string username, string password)
if (!RevertToSelf())
Console.WriteLine("RevertToSelf call to remove any prior impersonations failed");
throw new Exception("RevertToSelf call to remove any prior impersonations failed");
IntPtr token;
var result = LogonUser(username,
domain,
password,
LogonType.LOGON32_LOGON_INTERACTIVE,
LogonProvider.LOGON32_PROVIDER_DEFAULT,
out token);
if (!result)
var errorCode = Marshal.GetLastWin32Error();
Console.WriteLine(string.Format("Could not impersonate the elevated user. LogonUser: 2\\1 returned error code: 0.", errorCode, username, domain));
throw new Exception("Logon for user " + username + " failed.");
return token;
#endregion
这样:
var otherUserInSystemName = "probanduela";
var otherUserInSystemPassword = "chapuza";
var regularWin32AppPath = @"C:\Program Files (x86)\WinMerge\WinMergeU.exe";
var officeWin32AppPath = @"C:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE";
var ProcessId = CreateProcess.LaunchCommand(officeWin32AppPath, Environment.MachineName, otherUserInSystemName, otherUserInSystemPassword);
我总是收到错误:
1312: A specified logon session does not exist. It may already have been terminated.
也尝试了 CreateProcessWithLogonW,结果相同。
如果我尝试通过 PowerShell 或“runas”运行它,也会出现类似问题。
此方法在升级到 Windows 10 2004 版本之前有效,我已在不同的计算机上重现此方法。
有什么问题?我怎样才能实现我想做的事情?
-编辑-
刚刚发现使用 Excel v2002 build 12527.21104 可以工作;但使用 Excel v2008 build 13127.20408 失败。
显然是 Windows 10 v2004 + Office 2019 v2008 的组合导致了这个问题。
-编辑2-
如果我复制 EXCEL.EXE 并给它另一个名称,例如“EXCEL_COPY.EXE”,它可以工作:S
【问题讨论】:
你在 PowerShell 中尝试过Start-Process -FilePath Excel -Verb RunAs
吗?
您知道升级之前是什么版本吗?
您的目标是简单地“运行”程序还是尝试从外壳程序调用它。根据答案,我们可能需要更多详细信息,例如提到的@dxiv,或者如果您想运行 exe,只需在按住 Shift 键的同时右键单击可执行文件。上下文菜单将显示“以其他用户身份运行”选项。
@VantTech 这样做我得到了同样的错误,但在弹出窗口中 -> imgur.com/v0Ziyh0
@KUTlime 它产生与通过上下文菜单执行相同的结果,这是相同的错误但在弹出窗口中 -> imgur.com/v0Ziyh0 我最近发现制作 exe 文件的副本并在此执行而不是原创作品。不确定区别,因为两者的权限看起来相同:S
【参考方案1】:
我向微软报告了这个问题,在提升了几个级别后,他们已经着手解决并修复了。固定在Windows 10 Build 19042.844
【讨论】:
以上是关于Windows 2004 更新后无法以其他用户身份运行 EXCEL.EXE的主要内容,如果未能解决你的问题,请参考以下文章
无法以其他用户身份启动 Visual Studio 2015