Je vyžadována podpora jazyka JavaScript
Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.
Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.
ProcessUtil.cs
Download fileToto je zdrojový kód souboru ProcessUtil.cs
Class with RunCommandAs method to run an command under another user credentials.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
namespace IMP.Shared
{
internal static class ProcessUtil
{
#region NativeMethods class
private static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public class STARTUPINFO
{
public int cb;
public IntPtr lpReserved;
public IntPtr lpDesktop;
public IntPtr lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public class PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[Flags]
internal enum LogonFlags
{
//Log on, but use the specified credentials on the network only. The new process uses the same token as the caller, but the system creates
//a new logon session within LSA, and the process uses the specified credentials as the default credentials.
//This value can be used to create a process that uses a different set of credentials locally than it does remotely.
//This is useful in inter-domain scenarios where there is no trust relationship.
//The system does not validate the specified credentials. Therefore, the process can start, but it may not have access to network resources.
LOGON_NETCREDENTIALS_ONLY = 2,
//Log on, then load the user profile in the HKEY_USERS registry key. The function returns after the profile is loaded.
//Loading the profile can be time-consuming, so it is best to use this value only if you must access the information in the HKEY_CURRENT_USER registry key.
LOGON_WITH_PROFILE = 1
}
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool CreateProcessWithLogonW(string userName, string domain, IntPtr password, LogonFlags logonFlags, [MarshalAs(UnmanagedType.LPTStr)] string appName, System.Text.StringBuilder cmdLine, int creationFlags, IntPtr environmentBlock, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
#endregion
#region action methods
/// <summary>
/// Run an command under another user credentials.
/// </summary>
/// <param name="command">Executable file with arguments</param>
/// <param name="workingDirectory">Working directory</param>
/// <param name="user">Username with domain of desired credentials or null for Elevated Start</param>
/// <param name="password">Password of desired credentials</param>
/// <param name="showOutput">Show Output window</param>
/// <param name="netOnly">Indicates that the user information specified is for remote access only. (RunAs /NetOnly functionality)</param>
/// <param name="windowhandle">windowhandle for UAC dilog or IntPtr.Zero</param>
public static bool RunCommandAs(string command, string workingDirectory, string user, string password, bool netOnly, bool showOutput, IntPtr windowhandle)
{
string cmd = string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("COMSPEC")) ? "cmd.exe" : System.Environment.GetEnvironmentVariable("COMSPEC");
var startInfo = new ProcessStartInfo(cmd, "/c " + EncodeParameterArgument(command + (showOutput ? " & pause" : "")))
{
WorkingDirectory = workingDirectory,
LoadUserProfile = false,
CreateNoWindow = !showOutput,
WindowStyle = !showOutput ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal
};
if (string.IsNullOrEmpty(user))
{
startInfo.UseShellExecute = true;
startInfo.Verb = "runas"; //Start Elevated
}
else
{
string userName = ExtractLogin(user);
string domainName = ExtractDomain(user);
startInfo.UseShellExecute = false;
startInfo.Domain = domainName;
startInfo.UserName = userName;
startInfo.Password = MakeSecureString(password);
}
if (windowhandle != IntPtr.Zero)
{
//Make the UAC dialog modal to Windowhandle
startInfo.ErrorDialog = true;
startInfo.ErrorDialogParentHandle = windowhandle;
}
try
{
if (string.IsNullOrEmpty(user) || !netOnly)
{
//Run command normaly using Process class
var process = System.Diagnostics.Process.Start(startInfo);
//Wait for the process to end.
process.WaitForExit();
}
else
{
//Run command with RunAs /NetOnly functionality (CreateProcessWithLogonW with LOGON_NETCREDENTIALS_ONLY LogonFlag) and wait for the process to end.
StartProcessWithLogonNetOnly(startInfo, true);
}
return true;
}
catch (System.ComponentModel.Win32Exception ex)
{
try
{
//Provede publikaci vyjímky pomoci Exception Management Application Bloku
var additionalInfo = new System.Collections.Specialized.NameValueCollection();
additionalInfo.Add("Command", command);
additionalInfo.Add("WorkingDirectory", workingDirectory);
additionalInfo.Add("User", user);
additionalInfo.Add("Password", password);
Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex, additionalInfo);
}
catch (System.Exception publishex)
{
System.Windows.Forms.MessageBox.Show(publishex.ToString(), "Publish Error",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
}
if (string.IsNullOrEmpty(user))
{
//User cancelled UAC dialog
return false;
}
throw;
}
}
/// <summary>
/// Run an command under another user credentials.
/// </summary>
/// <param name="command">Executable file with arguments</param>
/// <param name="workingDirectory">Working directory</param>
/// <param name="user">Username with domain of desired credentials or null for Elevated Start</param>
/// <param name="password">Password of desired credentials</param>
/// <param name="netOnly">Indicates that the user information specified is for remote access only. (RunAs /NetOnly functionality)</param>
/// <param name="showOutput">Show Output window</param>
public static bool RunCommandAs(string command, string workingDirectory, string user, string password, bool netOnly, bool showOutput)
{
return RunCommandAs(command, workingDirectory, user, password, netOnly, showOutput, IntPtr.Zero);
}
/// <summary>
/// Run an command under another user credentials.
/// </summary>
/// <param name="command">Executable file with arguments</param>
/// <param name="workingDirectory">Working directory</param>
/// <param name="user">Username with domain of desired credentials or null for Elevated Start</param>
/// <param name="password">Password of desired credentials</param>
/// <param name="netOnly">Indicates that the user information specified is for remote access only. (RunAs /NetOnly functionality)</param>
public static bool RunCommandAs(string command, string workingDirectory, string user, string password, bool netOnly)
{
return RunCommandAs(command, workingDirectory, user, password, netOnly, false, IntPtr.Zero);
}
/// <summary>
/// Run an command under another user credentials.
/// </summary>
/// <param name="command">Executable file with arguments</param>
/// <param name="workingDirectory">Working directory</param>
/// <param name="user">Username with domain of desired credentials or null for Elevated Start</param>
/// <param name="password">Password of desired credentials</param>
public static bool RunCommandAs(string command, string workingDirectory, string user, string password)
{
return RunCommandAs(command, workingDirectory, user, password, false, false, IntPtr.Zero);
}
/// <summary>
/// Run an command under another user credentials.
/// </summary>
/// <param name="command">Executable file with arguments</param>
/// <param name="workingDirectory">Working directory</param>
public static bool RunCommandAs(string command, string workingDirectory)
{
return RunCommandAs(command, workingDirectory, null, null, false, false, IntPtr.Zero);
}
#endregion
#region private member functions
private static void StartProcessWithLogonNetOnly(ProcessStartInfo startInfo, bool waitForExit)
{
if (startInfo.UseShellExecute)
{
throw new InvalidOperationException("UseShellExecute must be false.");
}
if (startInfo.LoadUserProfile)
{
throw new InvalidOperationException("LoadUserProfile cannot be used.");
}
if (string.IsNullOrEmpty(startInfo.UserName))
{
throw new InvalidOperationException("UserName is empty.");
}
var cmdLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments);
var lpStartupInfo = new NativeMethods.STARTUPINFO();
var lpProcessInformation = new NativeMethods.PROCESS_INFORMATION();
int creationFlags = 0;
if (startInfo.CreateNoWindow)
{
creationFlags |= 0x8000000;
}
IntPtr zero = IntPtr.Zero;
string workingDirectory = startInfo.WorkingDirectory;
if (string.IsNullOrEmpty(workingDirectory))
{
workingDirectory = Environment.CurrentDirectory;
}
NativeMethods.LogonFlags logonFlags = NativeMethods.LogonFlags.LOGON_NETCREDENTIALS_ONLY; //NetOnly;
IntPtr passwordPrt = IntPtr.Zero;
try
{
if (startInfo.Password == null)
{
passwordPrt = Marshal.StringToCoTaskMemUni(string.Empty);
}
else
{
passwordPrt = Marshal.SecureStringToCoTaskMemUnicode(startInfo.Password);
}
int error = 0;
bool flag = NativeMethods.CreateProcessWithLogonW(startInfo.UserName, startInfo.Domain, passwordPrt, logonFlags, null, cmdLine, creationFlags, zero, workingDirectory, lpStartupInfo, lpProcessInformation);
if (!flag)
{
error = Marshal.GetLastWin32Error();
}
if (!flag)
{
if (error != 0xc1 && error != 0xd8)
{
throw new Win32Exception(error);
}
throw new Win32Exception(error, "Invalid Application");
}
}
finally
{
if (passwordPrt != IntPtr.Zero)
{
Marshal.ZeroFreeCoTaskMemUnicode(passwordPrt);
}
}
if (waitForExit)
{
NativeMethods.WaitForSingleObject(lpProcessInformation.hProcess, 0xFFFFFFFF);
}
}
private static StringBuilder BuildCommandLine(string executableFileName, string arguments)
{
StringBuilder builder = new StringBuilder();
string str = executableFileName.Trim();
bool flag = str.StartsWith("\"", StringComparison.Ordinal) && str.EndsWith("\"", StringComparison.Ordinal);
if (!flag)
{
builder.Append("\"");
}
builder.Append(str);
if (!flag)
{
builder.Append("\"");
}
if (!string.IsNullOrEmpty(arguments))
{
builder.Append(" ");
builder.Append(arguments);
}
return builder;
}
private static SecureString MakeSecureString(string text)
{
SecureString secure = new SecureString();
foreach (char c in text)
{
secure.AppendChar(c);
}
return secure;
}
/// <summary>
/// Encodes an argument for passing into a program
/// </summary>
/// <param name="original">The value that should be received by the program</param>
/// <returns>The value which needs to be passed to the program for the original value
/// to come through</returns>
public static string EncodeParameterArgument(string value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
value = "\"" + System.Text.RegularExpressions.Regex.Replace(value, @"(\\)+$", @"$1$1") + "\"";
return value;
}
/// <summary>
/// Vrací samotné přihlašovací jméno uživatele
/// </summary>
/// <param name="loginName">Přihlašovací jméno ve tvaru "domain\login" nebo "login@domain.local", případně pouze login</param>
/// <returns>Přihlašovací jméno uživatele</returns>
private static string ExtractLogin(string loginName)
{
string strExp = loginName.Replace("/", "\\");
int index = strExp.IndexOf('\\');
if (index != -1)
{
strExp = strExp.Substring(index + 1);
}
else
{
index = strExp.IndexOf('@');
if (index != -1)
{
strExp = strExp.Substring(0, index);
}
}
return strExp;
}
/// <summary>
/// Vrací název domeny z přihlašovacího jména uživatele
/// </summary>
/// <param name="loginName">Přihlašovací jméno ve tvaru "domain\login" nebo "login@domain.local", případně pouze login</param>
/// <returns>Název domeny uživatele</returns>
private static string ExtractDomain(string loginName)
{
string strExp = loginName.Replace("/", "\\");
int index = strExp.IndexOf('\\');
if (index != -1)
{
strExp = strExp.Substring(0, index);
}
else
{
index = strExp.IndexOf('@');
if (index != -1)
{
strExp = strExp.Substring(index + 1);
}
else
{
strExp = "";
}
}
index = strExp.IndexOf('.');
if (index != -1)
{
strExp = strExp.Substring(0, index);
}
return strExp.ToUpper(System.Globalization.CultureInfo.CurrentCulture);
}
#endregion
}
}