HelpViewerUIFramework.RunAsAdmin AdminRun = new RunAsAdmin(this.TestContext);
AdminRun.ExeCode = "HelpViewerUIFramework.RunAsAdminStaticMethod.ReadWriteRegedit.WriteRegistryValueEx(Microsoft.Win32.Registry.LocalMachine, HelpViewerUIFramework.HelpViewerSettings.DefaultStoreRegistryLocation, HelpViewerUIFramework.HelpViewerSettings.LocalStoreRegistryKey, @\"" + LocalStoreDefaultPath + "temp\");";
AdminRun.RunProcess();
--------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.Win32;
namespace HelpViewerUIFramework
{
public class RunAsAdmin
{
#region Fields
private string m_AddUsing = "";
private string m_PreClassCode = "";
private string m_PreMainCode = "";
private string m_ExeCode = "";
private const string m_RunAsAdminExeName = "RunAsAdmin.exe";
SHELLEXECUTEINFO m_lpExecInfo = new SHELLEXECUTEINFO();
private Microsoft.VisualStudio.TestTools.UnitTesting.TestContext m_testContext;
#endregion
#region Constructors
public RunAsAdmin(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext testContext)
{
this.m_testContext = testContext;
}
#endregion
#region proerpties
public string AddUsing
{
get { return m_AddUsing; }
set { m_AddUsing = value; }
}
public string PreClassCode
{
get { return m_PreClassCode; }
set { m_PreClassCode = value; }
}
public string PreMainCode
{
get { return m_PreMainCode; }
set { m_PreMainCode = value; }
}
public string ExeCode
{
get { return m_ExeCode; }
set { m_ExeCode = value; }
}
#endregion
#region ImportAPI
[StructLayout(LayoutKind.Sequential)]
private struct SHELLEXECUTEINFO //using in ShellExecuteEx
{
public int cbSize;
public uint fMask;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpVerb;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpParameters;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpDirectory;
public int nShow;
public IntPtr hInstApp;
public IntPtr lpIDList;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpClass;
public IntPtr hkeyClass;
public uint dwHotKey;
public IntPtr DUMMYUNIONNAME;
public IntPtr hProcess;
}
[System.Runtime.InteropServices.DllImport("Shell32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
[System.Runtime.InteropServices.DllImport("Kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[System.Runtime.InteropServices.DllImport("Kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint TerminateProcess(IntPtr hHandle, uint uExitCode);
#endregion
#region Method
private uint RunAdminProcess()
{
int SW_HIDE = 0;
uint SEE_MASK_NOCLOSEPROCESS = (0x00000040);
m_lpExecInfo.cbSize = Marshal.SizeOf(m_lpExecInfo);
m_lpExecInfo.lpVerb = "runas";
m_lpExecInfo.lpFile = this.m_testContext.DeploymentDirectory + "\\" + m_RunAsAdminExeName;
m_lpExecInfo.lpParameters = "";
m_lpExecInfo.nShow = SW_HIDE;
m_lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
return ShellExecuteEx(ref m_lpExecInfo);
}
private void CreateAdminProcess()
{
string code = "using System;" + System.Environment.NewLine +
m_AddUsing + System.Environment.NewLine +
"namespace RunAsAdmin" + System.Environment.NewLine +
"{" + System.Environment.NewLine +
" " + m_PreClassCode + System.Environment.NewLine +
" class Program" + System.Environment.NewLine +
" {" + System.Environment.NewLine +
" " + m_PreMainCode + System.Environment.NewLine +
" static void Main()" + System.Environment.NewLine +
" {" + System.Environment.NewLine +
" " + m_ExeCode + System.Environment.NewLine +
" }" + System.Environment.NewLine +
" }" + System.Environment.NewLine +
"}" + System.Environment.NewLine;
CompileCode(code, System.IO.Path.Combine(this.m_testContext.DeploymentDirectory, m_RunAsAdminExeName));
return;
}
private void CompileCode(string SourceCode, string ExeuteFileName)
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cp = new CompilerParameters(new string[] { "System.dll", System.IO.Path.Combine(this.m_testContext.DeploymentDirectory, "HelpViewerUIFramework.dll") }, ExeuteFileName, false);
cp.CompilerOptions = "/target:exe";
cp.IncludeDebugInformation = true;
cp.GenerateExecutable = true;
CompilerResults cr = provider.CompileAssemblyFromSource(cp, SourceCode);
if (cr.Errors.HasErrors)
{
StringBuilder error = new StringBuilder();
error.AppendLine("building error:");
foreach (CompilerError err in cr.Errors)
{
error.AppendFormat("{0}\n",err.ErrorText);
}
throw new Exception(error.ToString());
}
return;
}
public void RunProcess()
{
CreateAdminProcess();
if (RunAdminProcess() != 1)//TRUE
{
throw new Exception("RunProcess Error.");
}
if (WaitForSingleObject(m_lpExecInfo.hProcess, 30000) == 258L)//WAIT_TIMEOUT
{
TerminateProcess(m_lpExecInfo.hProcess, 0);
throw new Exception("RunProcess Timeout then be killed.");
}
}
#endregion
}
public static class RunAsAdminStaticMethod
{
public static class ReadWriteRegedit
{
/// <summary>
/// WinAPI extend for Regedit
/// </summary>
/// <history>create by hc 20101217</history>
[System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult);
[System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint RegQueryValueEx(IntPtr hKey, string lpValueName, IntPtr lpReserved, IntPtr lpType, Byte[] pvData, ref UInt32 lpcbData);
[System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint RegSetValueEx(IntPtr hKey, string lpValueName, uint Reserved, uint dwType, IntPtr lpData, uint cbData);
[System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint RegDeleteValue(IntPtr hKey, string lpValueName);
[System.Runtime.InteropServices.DllImport("Advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern uint RegCloseKey(IntPtr hKey);
/// <summary>
/// check if the system is a 64bit system
/// </summary>
/// <returns></returns>
private static bool Is32BitOperatingSystem()
{
Microsoft.Win32.RegistryKey localEnvironment = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
String processorArchitecture = (String)localEnvironment.GetValue("PROCESSOR_ARCHITECTURE");
return processorArchitecture.Equals("x86");
}
public static string ReadRegistryValueEx(Microsoft.Win32.RegistryKey baseKeyName, string subKey, string KeyName)
{
const long ERROR_SUCCESS = 0L;
const int KEY_QUERY_VALUE = (0x0001);
const int KEY_READ = (0x20019);
const int KEY_WOW64_64KEY = (0x0100);
int KEY_VALUE = 0;
IntPtr REGISTRYKEY = new IntPtr(0x0000);
IntPtr hKey = new IntPtr(0x0000);
long ERROR_CODE = 0;
if (baseKeyName == Microsoft.Win32.Registry.ClassesRoot)
{
REGISTRYKEY = (IntPtr)(-2147483648);
}
else if (baseKeyName == Microsoft.Win32.Registry.CurrentUser)
{
REGISTRYKEY = (IntPtr)(-2147483647);
}
else if (baseKeyName == Microsoft.Win32.Registry.LocalMachine)
{
REGISTRYKEY = (IntPtr)(-2147483646);
}
else if (baseKeyName == Microsoft.Win32.Registry.Users)
{
REGISTRYKEY = (IntPtr)(-2147483645);
}
if (Is32BitOperatingSystem())//32bit
{
KEY_VALUE = KEY_QUERY_VALUE | KEY_READ;
}
else//64bit
{
KEY_VALUE = (KEY_QUERY_VALUE | KEY_READ | KEY_WOW64_64KEY);
}
ERROR_CODE = RegOpenKeyEx(REGISTRYKEY, subKey, 0, KEY_VALUE, out hKey);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Open Regedit Error:{0}", ERROR_CODE));
}
UInt32 size = 0;
ERROR_CODE = RegQueryValueEx(hKey, KeyName, IntPtr.Zero, IntPtr.Zero, null, ref size);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Get Regedit Value Error:{0}", ERROR_CODE));
}
Byte[] value = new Byte[size];
ERROR_CODE = RegQueryValueEx(hKey, KeyName, IntPtr.Zero, IntPtr.Zero, value, ref size);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Get Regedit Value Error:{0}", ERROR_CODE));
}
ERROR_CODE = RegCloseKey(REGISTRYKEY);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Close Regedit Error:{0}", ERROR_CODE));
}
return Encoding.Unicode.GetString(value).TrimEnd('\0');
}
public static bool WriteRegistryValueEx(Microsoft.Win32.RegistryKey baseKeyName, string subKey, string KeyName, string KeyValue)
{
const long ERROR_SUCCESS = 0L;
const int KEY_SET_VALUE = (0x0002);
const int KEY_WOW64_64KEY = (0x0100);
int KEY_VALUE = 0;
IntPtr REGISTRYKEY = new IntPtr(0x0000);
IntPtr hKey = new IntPtr(0x0000);
uint REG_SZ = 1;
long ERROR_CODE = 0;
if (baseKeyName == Microsoft.Win32.Registry.ClassesRoot)
{
REGISTRYKEY = (IntPtr)(-2147483648);
}
else if (baseKeyName == Microsoft.Win32.Registry.CurrentUser)
{
REGISTRYKEY = (IntPtr)(-2147483647);
}
else if (baseKeyName == Microsoft.Win32.Registry.LocalMachine)
{
REGISTRYKEY = (IntPtr)(-2147483646);
}
else if (baseKeyName == Microsoft.Win32.Registry.Users)
{
REGISTRYKEY = (IntPtr)(-2147483645);
}
if (Is32BitOperatingSystem())//32bit
{
KEY_VALUE = KEY_SET_VALUE;
}
else//64bit
{
KEY_VALUE = (KEY_SET_VALUE | KEY_WOW64_64KEY);
}
ERROR_CODE = RegOpenKeyEx(REGISTRYKEY, subKey, 0, KEY_VALUE, out hKey);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Open Regedit Error:{0}", ERROR_CODE));
}
ERROR_CODE = RegSetValueEx(hKey, KeyName, 0, REG_SZ, System.Runtime.InteropServices.Marshal.StringToHGlobalAuto(KeyValue), (uint)(KeyValue.Length * 2));
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Set Regedit Value Error:{0}", ERROR_CODE));
}
ERROR_CODE = RegCloseKey(REGISTRYKEY);
if (ERROR_SUCCESS != ERROR_CODE)
{
throw new System.Exception(String.Format("Close Regedit Error:{0}", ERROR_CODE));
}
return true;
}
public static string ReadRegistryValue(RegistryKey baseKeyName, string subKey, string KeyName)
{
RegistryKey rk = baseKeyName;
RegistryKey sk = rk.OpenSubKey(subKey);
if (sk == null)
return "";
else
{
string val = (string)sk.GetValue(KeyName);
return val == null ? "" : val;
}
}
public static int ReadRegistryIntValue(RegistryKey baseKeyName, string subKey, string KeyName)
{
RegistryKey rk = baseKeyName;
RegistryKey sk = rk.OpenSubKey(subKey);
if (sk == null)
return -1;
else
{
int val = (int)sk.GetValue(KeyName);
return val == null ? -1 : val;
}
}
public static bool WriteRegistryValue(RegistryKey baseKeyName, string subKey, string KeyName, string KeyValue)
{
RegistryKey rk = baseKeyName;
RegistryKey sk = rk.OpenSubKey(subKey, true);
if (sk == null)
{
return false;
}
sk.SetValue(KeyName, KeyValue, RegistryValueKind.String);
return true;
}
public static bool WriteRegistryIntValue(RegistryKey baseKeyName, string subKey, string KeyName, int KeyValue)
{
RegistryKey rk = baseKeyName;
RegistryKey sk = rk.OpenSubKey(subKey, true);
if (sk == null)
{
return false;
}
sk.SetValue(KeyName, KeyValue, RegistryValueKind.DWord);
return true;
}
}
}
}