gpt4 book ai didi

C# Winform 模拟无法工作

转载 作者:太空宇宙 更新时间:2023-11-03 14:26:42 25 4
gpt4 key购买 nike

我刚刚花了 2 天时间阅读了一堆关于 C# 模拟的资料(包括 stackoverflow 和 codeproject 文章),这是我的调查结果。

简而言之,我只想从在标准(非特权)用户帐户下运行的 winform 应用程序启动和停止服务。我想用管理员帐户模拟我的用户。两个账户都是本地账户。

在下面的代码中,我在 token 检索期间没有收到任何错误(通过互操作调用),但对 servicecontroller.Start 和 servicecontroller.Stop 的调用总是失败。

网络上的所有文章都描述了模拟用户的相同过程,但直到现在,我都无法让它工作,甚至无法获得有关问题所在的线索。

有没有人知道那里出了什么问题......

提前致谢

--布鲁诺

     public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
private void button1_Click(object sender, EventArgs e)
{


WindowsImpersonationContext wic = ImpersonateUser(
"Administrator",
"machinename",
"password");

try
{
ServiceController sc = new ServiceController("SERVICE_PERE");
Process p = new Process();


sc.Start();
}
catch (Exception ex)
{

Debugger.Break();
}
finally
{
wic.Undo();
}


}

private void button2_Click(object sender, EventArgs e)
{
WindowsImpersonationContext wic = ImpersonateUser(
"Administrator",
"machinename",
"password");


try
{

ServiceController sc = new ServiceController("SERVICE_PERE");

sc.Stop();
}
catch (Exception ex)
{
Debugger.Break();

}
finally
{
wic.Undo();
//CodeAccessPermission.RevertAssert();
}
}
public WindowsImpersonationContext ImpersonateUser(string sUsername, string sDomain, string sPassword)
{
// initialize tokens

IntPtr pExistingTokenHandle = new IntPtr(0);
IntPtr pDuplicateTokenHandle = new IntPtr(0);
pExistingTokenHandle = IntPtr.Zero;
pDuplicateTokenHandle = IntPtr.Zero;

// if domain name was blank, assume local machine

if (sDomain == "")
sDomain = System.Environment.MachineName;

try
{
string sResult = null;

const int LOGON32_PROVIDER_DEFAULT = 0;

// create token

const int LOGON32_LOGON_INTERACTIVE = 2;
//const int SecurityImpersonation = 2;


// get handle to token

bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref pExistingTokenHandle);

// did impersonation fail?

if (false == bImpersonated)
{
int nErrorCode = Marshal.GetLastWin32Error();
sResult = "LogonUser() failed with error code: " +
nErrorCode + "\r\n";

// show the reason why LogonUser failed

//MessageBox.Show(this, sResult, "Error",
// MessageBoxButtons.OK, MessageBoxIcon.Error);
}

// Get identity before impersonation

sResult += "Before impersonation: " +
WindowsIdentity.GetCurrent().Name + "\r\n";

bool bRetVal = DuplicateToken(pExistingTokenHandle,
2, ref pDuplicateTokenHandle);

// did DuplicateToken fail?

if (false == bRetVal)
{
int nErrorCode = Marshal.GetLastWin32Error();
// close existing handle

CloseHandle(pExistingTokenHandle);
sResult += "DuplicateToken() failed with error code: "
+ nErrorCode + "\r\n";

// show the reason why DuplicateToken failed

//MessageBox.Show(this, sResult, "Error",
// MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
else
{
// create new identity using new primary token

WindowsIdentity newId = new WindowsIdentity
(pDuplicateTokenHandle);

WindowsImpersonationContext impersonatedUser =
newId.Impersonate();

// check the identity after impersonation

sResult += "After impersonation: " +
WindowsIdentity.GetCurrent().Name + "\r\n";

//MessageBox.Show(this, sResult, "Success",
// MessageBoxButtons.OK, MessageBoxIcon.Information);
return impersonatedUser;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
// close handle(s)

if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}
}

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,
}
public enum LogonProvider
{
LOGON32_PROVIDER_DEFAULT = 0,
}

最佳答案

启动和停止服务需要管理员权限。您不能通过模拟绕过 UAC,您必须显示提升提示。 This answer向您展示如何。

关于C# Winform 模拟无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3780313/

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