我有一个只使用管理员权限运行的程序(通过上下文菜单)。如何创建使用本地管理员凭据运行应用程序的脚本?
我有什么:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//copy from
string sourcePath = @"\\10.11.11.4\Links\";
//copy to
string targetPath = @"e:\RainbowPlus\Links\";
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
foreach (var srcPath in Directory.GetFiles(sourcePath))
{
File.Copy(srcPath, srcPath.Replace(sourcePath, targetPath), true);
}
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = @"C:\Program Files\WinRAR\RAR.exe";
//unrar and overwrite to
ps.Arguments = @"x -o+ e:\RainbowPlus\Links\Links.rar e:\RainbowPlus\Links\";
Process.Start(ps);
}
private void button2_Click(object sender, EventArgs e)
{
Process proc = new Process
{
StartInfo =
{
CreateNoWindow = true,
UseShellExecute = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
FileName = @"E:\\RainbowPlus\\Rainbowplus.exe",
UserName = "username",
Domain = "my.domain",
Password = GetSecureString("secretpassword"),
Arguments = ""
}
};
//proc.Start();
Process p = new Process();
p.StartInfo.Verb = "runas";
System.Diagnostics.Process.Start("E:\\RainbowPlus\\Rainbowplus.exe");
}
public static SecureString GetSecureString(string str)
{
SecureString secureString = new SecureString();
foreach (char ch in str)
{
secureString.AppendChar(ch);
}
secureString.MakeReadOnly();
return secureString;
}
但我仍然有UAC承诺。 为此,我使用bat文件:
@echo off
REM Check runing program ####
Set ProcessName=rainbowplus.exe
TaskList /FI "ImageName EQ %ProcessName%" | Find /I "%ProcessName%"
If %ErrorLevel%==0 (echo Close rainbow program) else (goto testnetwork)
pause
exit
REM Network testing
:testnetwork
echo Testing network
pause
ping -n 4 10.11.11.4 | find "TTL=" > nul
if %errorlevel%==0 (goto copy) else (echo Network down)
pause
exit
REM Copy files
:copy
echo Updating files
pause
xcopy "\\10.11.11.4\Links" "E:\RainbowPlus\Links" /i /q /e /y /h /c
if %errorlevel%==0 (goto startprogram) else (goto error)
:startprogram
echo Succsess
pause
runas.exe /env /profile /savecred /user:"comp5234\Administrator" "E:\RainbowPlus\RainbowPlus.exe"
exit
:error
echo Files was not updated
pause
exit
我的问题在哪里?
答案 0 :(得分:0)
试试这个。在项目中添加应用程序清单文件。然后在清单文件中添加以下行。
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
在使用Visual Studio时,右键单击Project - &gt;添加新项,然后选择Application Manifest File添加应用程序清单文件
答案 1 :(得分:0)
在您的程序中模拟管理员用户然后在被模拟为管理员用户时启动外部进程是有效的。
交互式用户仍会看到UAC确认(除非您的应用程序已经使用提升的权限运行),但他们不必输入凭据,只需单击“确定”,即可使用模拟管理员用户的凭据。
使用以下源代码:
private void Impersonate()
{
IntPtr token = IntPtr.Zero;
if (LogonUser("adminusername", "", "Password", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out token))
{
throw new Win32Exception();
}
WindowsIdentity.Impersonate(token);
}
private void button1_Click(object sender, EventArgs e)
{
Impersonate();
try
{
Process process = new Process();
process.StartInfo.FileName = "ABC.exe";
process.StartInfo.UseShellExecute = false;
process.Start();
}
finally
{
RevertToSelf();
}
}
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool LogonUser(
[MarshalAs(UnmanagedType.LPStr)] string pszUserName,
[MarshalAs(UnmanagedType.LPStr)] string pszDomain,
[MarshalAs(UnmanagedType.LPStr)] string pszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool RevertToSelf();
请注意,您必须使用UseShellExecute = false
。