C#实现Windows开机自启动

Windows开机自启动的API原理是向注册表

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

对应应用程序的运行路径,或者说启动命令,允许带参数。

HKEY_CURRENT_USER与HKEY_LOCAL_MACHINE

注册表HKEY_CURRENT_USER节点下的内容仅针对当前登录的用户生效,Windows是多账户系统(不是多用户系统,多用户允许同时多个用户登录使用当前计算机系统),不同账户下有不同的配置。

注册表HKEY_LOCAL_MACHINE节点下的内容都是针对系统所有用户生效的。

C#可以直接调用Windows API接口读写注册表

第一、实现写注册表的函数

private static bool WriteRegistryValue(RegistryKey regKey, String keyName, String value)
{
	if (null == keyName || 0 == keyName.Trim().Length)
	{
		Console.WriteLine("WriteRegistryValue, invalid keyName: " + keyName);
		return false;
	}
	if (null == value || 0 == value.Trim().Length)
	{
		Console.WriteLine("WriteRegistryValue, invalid value: " + value);
		return false;
	}
	try
	{
		bool needChange = false;
		String[] names = regKey.GetValueNames();
		if (null != names)
		{
			for (int i = 0; i < names.Length; i++)
			{
				String oldValue = (String)regKey.GetValue(keyName, "");
				if (null == oldValue || !oldValue.Equals(value))
				{
					needChange = true;
					break;
				}
			}
		}
		if (needChange)
		{
			regKey.SetValue(keyName, value);
		}
		return true;
	}
	catch (SecurityException e)
	{
		Console.WriteLine("WriteRegistryValue, SecurityException ");
	}
	catch (ObjectDisposedException e)
	{
		Console.WriteLine("WriteRegistryValue, ObjectDisposedException");
	}
	catch (System.IO.IOException e)
	{
		Console.WriteLine("WriteRegistryValue, IOException");
	}
	catch (UnauthorizedAccessException e)
	{
		Console.WriteLine("WriteRegistryValue, IOException");
	}
	return false;
}

第二、实现向注册表节点Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run写入数值的函数

public static String getAutoStartKeyName(String softwareName, String softwarePath)
{
	if (null == softwareName || 0 == softwareName.Trim().Length)
	{
		return "";
	}
	if (null == softwarePath || 0 == softwarePath.Trim().Length)
	{
		return "";
	}
	String md5sum = Md5sum(softwarePath);
	return softwareName + "_" + md5sum.Substring(0, 8);
}

public static bool setAutoStart(String softwareName, String softwarePath)
{
	if (null == softwareName || 0 == softwareName.Trim().Length)
	{
		Console.WriteLine("invalid softwareName: " + softwareName);
		return false;
	}

	if (null == softwarePath || 0 == softwarePath.Trim().Length)
	{
		Console.WriteLine("invalid softwarePath: " + softwarePath);
		return false;
	}

	RegistryKey localMachineKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
	RegistryKey regKeyRun = localMachineKey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
	RegistryKey regKeySoftware = null, regKeyMiscrosoft = null, regKeyWindows = null, regKeyCurrentVersion = null;
	try
	{
		if (null == regKeyRun)
		{
			Console.WriteLine("openSubKey failed. try create it.");
			regKeySoftware = localMachineKey.CreateSubKey("Software");
			regKeyMiscrosoft = regKeySoftware.CreateSubKey("Microsoft");
			regKeyWindows = regKeyMiscrosoft.CreateSubKey("Windows");
			regKeyCurrentVersion = regKeyWindows.CreateSubKey("CurrentVersion");
			regKeyRun = regKeyCurrentVersion.CreateSubKey("Run");
		}

		String keyName = getAutoStartKeyName(softwareName, softwarePath);
		return WriteRegistryValue(regKeyRun, keyName, softwarePath);
	}
	finally
	{
		SafeCloseRegKey(regKeyRun); regKeyRun = null;
		SafeCloseRegKey(regKeyCurrentVersion); regKeyCurrentVersion = null;
		SafeCloseRegKey(regKeyWindows); regKeyWindows = null;
		SafeCloseRegKey(regKeyMiscrosoft); regKeyMiscrosoft = null;
		SafeCloseRegKey(regKeySoftware); regKeySoftware = null;
	}
}

private static void SafeCloseRegKey(RegistryKey regKey)
{
	if (null != regKey)
	{
		regKey.Close();
	}
}


public static String Md5sum(String input)
{
	// step 1, calculate MD5 hash from input
	System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();

	byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
	byte[] hash = md5.ComputeHash(inputBytes);

	// step 2, convert byte array to hex string
	StringBuilder sb = new StringBuilder();
	for (int i = 0; i < hash.Length; i++)
	{
		sb.Append(hash[i].ToString("X2"));
	}

	return sb.ToString();
}

大家注意到String getAutoStartKeyName(String softwareName, String softwarePath)函数,这里是为了防止注册表中的name存在相同的情况造成冲突,因此将程序路劲也放进去MD5计算生成唯一的name保证不会冲突。

第三、实现关闭自启动

其实就是将自启动信息从注册表中删除

public static bool RemoveAutoStart(String softwarePath)
{
	if (null == softwarePath || 0 == softwarePath.Trim().Length)
	{
		return false;
	}
	RegistryKey localMachineKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
	RegistryKey regKeyRun = localMachineKey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
	if (null == regKeyRun)
	{
		return false;
	}
	try
	{
		String[] names = regKeyRun.GetValueNames();
		if (null == names || 0 == names.Length)
		{
			return false;
		}

		String value;
		foreach (String name in names)
		{
			value = (String)regKeyRun.GetValue(name, "");
			if (softwarePath.Equals(value))
			{
				regKeyRun.DeleteValue(name);
				return true;
			}
		}
	}
	catch (SecurityException e)
	{
		Console.WriteLine("SecurityException");
	}
	catch (ObjectDisposedException e)
	{
		Console.WriteLine("ObjectDisposedException");
	}
	catch (System.IO.IOException e)
	{
		Console.WriteLine("IOException");
	}
	catch (UnauthorizedAccessException e)
	{
		Console.WriteLine("IOException");
	}
	finally
	{
		SafeCloseRegKey(regKeyRun); regKeyRun = null;
	}
	return false; // TODO
}

第四、实现判断当前路径是否有自启动的方法

因为在本人工具中只设置当前用户的自启动,所以判断时只判断当前用户,如果需要所有用户请使用HKEY_LOCAL_MACHINE对应的参数

public static bool IsAutoStart(String softwarePath)
{
	if (null == softwarePath || 0 == softwarePath.Trim().Length)
	{
		return false;
	}
	RegistryKey localMachineKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
	RegistryKey regKeyRun = localMachineKey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
	if (null == regKeyRun)
	{
		return false;
	}
	try
	{
		String[] names = regKeyRun.GetValueNames();
		if (null == names || 0 == names.Length)
		{
			return false;
		}

		String value;
		foreach (String name in names)
		{
			value = (String)regKeyRun.GetValue(name, "");
			if (softwarePath.Equals(value))
			{
				return true;
			}
		}
	}
	catch (SecurityException e)
	{
		Console.WriteLine("SecurityException");
	}
	catch (ObjectDisposedException e)
	{
		Console.WriteLine("ObjectDisposedException");
	}
	catch (System.IO.IOException e)
	{
		Console.WriteLine("IOException");
	}
	catch (UnauthorizedAccessException e)
	{
		Console.WriteLine("IOException");
	}
	finally
	{
		SafeCloseRegKey(regKeyRun); regKeyRun = null;
	}
	return false;
}

因为小工具是自己使用的,所以没有考虑到全局用户,全局用户需要administrator权限,大家用VS编译时增加对应权限就可以了。

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值