网友阿东提示了这样一个需求:写一个小程序把指定目录的程序添加到开机自动启动,跳过360
我就到百度上搜了一下:http://www.cnblogs.com/zcm123/archive/2012/06/07/2540339.html
using Microsoft.Win32;
#region 将程序添加到启动项 /// <summary> /// 注册表操作,将程序添加到启动项 /// </summary> public static void SetRegistryApp() { try { Microsoft.Win32.RegistryKey Reg; string ShortFileName = Application.ProductName; Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (Reg == null) { Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); } Reg.SetValue(ShortFileName, Application.ExecutablePath); } catch (Exception ex) { MessageBox.Show(ex.Message); } } #endregion #region 将程序从启动项中删除 /// <summary> /// 注册表操作,删除注册表中启动项 /// </summary> public static bool DeleteRegisterApp() { string ShortFileName = Application.ProductName; //获得应用程序名 try { Microsoft.Win32.RegistryKey Reg; Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (Reg == null) { Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); } Reg.DeleteValue(ShortFileName, false); } catch (Exception ex) { return false; } return true; } #endregion /// <summary> /// 检查当前程序是否在启动项中 /// </summary> /// <returns></returns> public static bool CheckExistRegisterApp() { string ShortFileName = Application.ProductName; //获得应用程序名 bool bResult = false; try { Microsoft.Win32.RegistryKey Reg; Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (Reg == null) { Reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); } foreach (string s in Reg.GetValueNames()) { if (s.Equals(ShortFileName)) { bResult = true; break; } } } catch (Exception ex) { return false; } return bResult; }
写一个程序测试结果提示:不允许所请求的注册表访问权"
解决办法如下:
一、可以直接用管理员权限安装打开和卸载该软件
二、在XP/2003下调试得好好的程序,到了windows7下,却抛出“不允许所请求的注册表访问权”的异常,该异常就在读写注册表时引发,例:
public class Program
{
public static void SetAutoRun(string keyName, string filePath)
{
using (RegistryKey runKey = Registry.LocalMachine.OpenSubKey(@"software\microsoft\windows\currentversion\run", true))
{
runKey.SetValue(keyName, filePath);
runKey.Close();
}
}
static void Main()
{
string keyName = "TestAutoRun";
string fliePath = @"D:\CSharpProject\CSharp_Learn\MyDelegate.exe";
SetAutoRun(keyName, fliePath);
}
}
}
该程序如在windows 7下运行,需以管理员权限运行。
【方法一】
代码访问安全性策略必须向使用 Microsoft.Win32.Registry 类访问注册表的代码授予 RegistryPermission。这个权限类型可以用于限制对特定注册表项和子注册表项的注册表访问,还可以控制代码读取、写入或创建注册表项和已命名的值的能力。
要约束代码对特定注册表项的访问,可以使用带 SecurityAction.PermitOnly 的 RegistryPermissionAttribute。下面的属性确保代码仅可以读 HKEY_LOCAL_MACHINE\SOFTWARE 下面的 YourApp 注册表项(及子项)。
[RegistryPermissionAttribute(SecurityAction.PermitOnly, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")] public static string GetConfigurationData( string key, string namedValue ) { return (string)Registry. LocalMachine. OpenSubKey(key). GetValue(namedValue); }
要记录代码的权限要求,并确保在代码访问安全性策略没有授予它充分的注册表访问权限时程序集无法加载,应当添加带 SecurityAction.RequestMinimum 的程序集级 RegistryPermissionAttribute,如下面的示例所示。
[assembly:RegistryPermissionAttribute(SecurityAction.RequestMinimum, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")]
【方法二】
添加 应用程序清单文件,在其中加入
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果希望更改 Windows 用户帐户控制级别,请用以下节点之一替换
requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
如果您希望利用文件和注册表虚拟化提供
向后兼容性,请删除 requestedExecutionLevel 节点。
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
修改代码,如下:
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal( identity );
if(principal.IsInRole( System.Security.Principal.WindowsBuiltInRole.Administrator ))
{
// 修改注册表
}
else
{
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = System.Windows.Forms.Application.ExecutablePath; // 获取当前可执行文件的路径及文件名
//以下 Args 为启动本程序的对应的参数
startInfo.Arguments = String.Join( " ", Args );
startInfo.Verb = "runas";
System.Diagnostics.Process.Start( startInfo );
}