I want to create a shortcut icon on Today's screen, and want to remove
it using C#... does anyone knows how to achieve it? I have seen for
Startup or Start menu, which is ok, but not sure about on Today's
screen.
Thanks
============
== C# Code
============
/// <summary>
/// Enable and Disable Today Screen Items
/// </summary>
public class Today
{
/// <summary>
/// Checks the RegistryImpl if the Today Screen item exists
/// </summary>
/// <param name="item">Item Name</param>
/// <returns>returns TRUE if the item exists, otherwise FALSE</returns>
public static bool DoesItemExist(string item)
{
uint key = 0;
string subkey = string.Format(@"SOFTWARE\Microsoft\Today\Items\{0}",
item);
if (RegistryImpl.RegOpenKeyEx((uint)RegistryImpl.RootKey.HKEY_LOCAL_MACHINE,
subkey, 0, 0, ref key) == 0)
{
RegistryImpl.RegCloseKey(key);
return true;
}
else return false;
}
/// <summary>
/// Checks the registry if the item is enabled
/// </summary>
/// <param name="item">Item Name</param>
/// <returns>returns TRUE if the item exists and is enabled, otherwise
FALSE</returns>
public static bool IsItemEnabled(string item)
{
uint key = 0;
string subkey = string.Format(@"SOFTWARE\Microsoft\Today\Items\{0}",
item);
if (RegistryImpl.RegOpenKeyEx((uint)RegistryImpl.RootKey.HKEY_LOCAL_MACHINE,
subkey, 0, 0, ref key) == 0)
{
int type = 0;
int size = 0;
byte[] data = null;
if (RegistryImpl.RegQueryValueEx(key, subkey, 0, ref type,
data, ref size) == 0)
{
data = new byte[size];
if (RegistryImpl.RegQueryValueEx(key, subkey, 0, ref
type, data, ref size) == 0)
{
if (type != RegistryImpl.REG_DWORD)
return false;
}
else return false;
return ((uint)BitConverter.ToInt32(data, 0) == 1) ? true
: false;
}
else return false;
}
else return false;
}
/// <summary>
/// Causes the Today screen to re-read from the RegistryImpl
/// </summary>
public static void RefreshTodayScreen()
{
Window.SendMessage("DesktopWindowExplorer", "Desktop",
WindowMessages.WM_WININICHANGE, 0x000000F2,
0);
}
/// <summary>
/// Enable the Today Screen item
/// </summary>
/// <param name="item">Item Name</param>
/// <returns>returns TRUE if successful, otherwise FALSE</returns>
public static bool EnableTodayScreen(string item)
{
bool status = false;
int err = 0;
uint key = 0;
string subkey = string.Format(@"SOFTWARE\Microsoft\Today\Items\{0}",
item);
if (RegistryImpl.RegOpenKeyEx((uint)RegistryImpl.RootKey.HKEY_LOCAL_MACHINE,
subkey, 0, 0, ref key) == 0)
{
byte[] value = BitConverter.GetBytes(1);
subkey = string.Format(@"{0}\Enabled", subkey);
err = RegistryImpl.RegSetValueEx(key, subkey, 0, RegistryImpl.REG_DWORD,
value, value.Length);
status = (err == 0) ? true : false;
err = RegistryImpl.RegCloseKey(key);
status = (err == 0) ? true : false;
status = Window.SendMessage("DesktopWindowExplorer", "Desktop",
WindowMessages.WM_WININICHANGE,
0x000000F2, 0);
return status;
}
else return false;
}
/// <summary>
/// Disables the Today Screen item
/// </summary>
/// <param name="item">Item Name</param>
/// <returns>returns TRUE if successful, otherwise FALSE</returns>
public static bool DisableTodayScreen(string item)
{
bool status = false;
int err = 0;
uint key = 0;
string subkey = string.Format(@"SOFTWARE\Microsoft\Today\Items\{0}",
item);
if (RegistryImpl.RegOpenKeyEx((uint)RegistryImpl.RootKey.HKEY_LOCAL_MACHINE,
subkey, 0, 0, ref key) == 0)
{
byte[] value = BitConverter.GetBytes(0);
subkey = string.Format(@"{0}\Enabled", subkey);
err = RegistryImpl.RegSetValueEx(key, subkey, 0, RegistryImpl.REG_DWORD,
value, value.Length);
status = (err == 0) ? true : false;
err = RegistryImpl.RegCloseKey(key);
status = (err == 0) ? true : false;
Window.SendMessage("DesktopWindowExplorer", "Desktop",
WindowMessages.WM_WININICHANGE, 0x000000F2,
0);
return status;
}
else return false;
}
}
/// <summary>
/// Represents a key level node in the Windows registry.
/// This class is a registry encapsulation.
/// </summary>
public sealed class RegistryKey : IDisposable
{
private bool m_bReadOnly = true;
private uint m_uiHKey = 0;
private string m_sName = null;
/// <summary>
/// This method should only be called by the Registry class to set
up the root keys!
/// </summary>
/// <param name="rootKey"></param>
internal RegistryKey(uint rootKey, string rootKeyName)
{
m_uiHKey = RegistryImpl.OpenKey(rootKey, "");
m_bReadOnly = true;
m_sName = rootKeyName;
}
internal RegistryKey(uint rootKey, string rootKeyName, string subkey)
{
RegistryImpl.KeyDisposition disp = 0;
m_uiHKey = RegistryImpl.CreateKey(rootKey, subkey, null, ref
disp);
m_bReadOnly = false;
m_sName = rootKeyName + "\\" + subkey;
}
/// <summary>
/// Closes the key and flushes it to disk if the contents have been
modified.
/// </summary>
~RegistryKey()
{
Dispose();
}
/// <summary>
/// Closes the key and flushes it to disk if the contents have been
modified.
/// </summary>
public void Close()
{
if (m_uiHKey != 0)
{
RegistryImpl.RegCloseKey(m_uiHKey);
m_uiHKey = 0;
}
}
/// <summary>
/// Creates a new subkey or opens an existing subkey. The string
subKey is not case-sensitive.
/// </summary>
/// <param name="subkey">Name or path of subkey to create or open.
</param>
/// <returns>Returns the subkey, or null if the operation failed.</returns>
public RegistryKey CreateSubKey(string subkey)
{
AssertIsOpen();
return new RegistryKey(m_uiHKey, Name, subkey);
}
/// <summary>
/// Deletes the specified subkey. The string subkey is not case-sensitive.
/// </summary>
/// <param name="subkey">Name of the subkey to delete.</param>
/// <param name="throwOnMissing">Indicates whether an exception should
be raised
/// if the specified subkey cannot be found. If this argument is
true and the
/// specified subkey does not exist then an exception is raised.
If this argument
/// is false and the specified subkey does not exist, then no action
is taken
/// </param>
public void DeleteSubKey(string subkey, bool throwOnMissing)
{
AssertIsOpen();
// make sure we are not read only
if (m_bReadOnly)
throw new UnauthorizedAccessException("The subkey cannot
be deleted. The registry key was opened as read only");
// do the check to see if the key actually exists
uint retKey = 0;
int retVal = RegistryImpl.RegOpenKeyEx(m_uiHKey, subkey, 0, 0,
ref retKey);
if (retVal != 0)
{
if (throwOnMissing)
throw new Exception("The subkey " + subkey + " cannot
be deleted because it is missing.");
return;
}
// check and see if the subkey to delete has any subkeys of its
own
char[] chNull = null;
int iNull = 0;
int cSubKey = 1;
RegistryImpl.RegQueryInfoKey(retKey, chNull, ref iNull, 0, ref
cSubKey, ref iNull, ref iNull, ref iNull,
ref iNull, ref iNull, 0, 0);
if (cSubKey != 0)
{
RegistryImpl.RegCloseKey(retKey);
throw new InvalidOperationException("The specified subkey
has child keys");
}
// we are all good, delete the key
RegistryImpl.RegDeleteKey(m_uiHKey, subkey);
}
/// <summary>
/// Deletes the specified subkey. The string subkey is not case-sensitive.
/// </summary>
/// <param name="subkey">Name of the subkey to delete.</param>
public void DeleteSubKey(string subkey)
{
// just call the overloaded function
DeleteSubKey(subkey, false);
}
/// <summary>
/// Deletes a subkey and any child subkeys recursively. The string
subKey is not case-sensitive.
/// </summary>
/// <param name="subkey">Subkey to delete</param>
public void DeleteSubKeyTree(string subkey)
{
AssertIsOpen();
// make sure we are not read only
if (m_bReadOnly)
throw new UnauthorizedAccessException("The subkey cannot
be deleted. The registry key was opened as read only");
// delete the key
RegistryImpl.RegDeleteKey(m_uiHKey, subkey);
}
/// <summary>
/// Deletes the specified value from this key. The string subKey
is not case sensitive.
/// </summary>
/// <param name="val">Name of the value to delete.</param>
/// <param name="throwOnMissing">Indicates whether an exception should
be raised
/// if the specified value cannot be found. If this argument is true
and the specified
/// value does not exist then an exception is raised. If this argument
is false and
/// the specified value does not exist, then no action is taken</param>
public void DeleteValue(string val, bool throwOnMissing)
{
AssertIsOpen();
// make sure we are not read only.
if (m_bReadOnly)
throw new UnauthorizedAccessException("The value cannot be
deleted. The registry key was opened as read only");
if (throwOnMissing)
{
// do the check to see if the key actually exists
int type = 0;
int size = 0;
byte[] data = null;
if (RegistryImpl.RegQueryValueEx(m_uiHKey, val, 0, ref type,
data, ref size) != 0)
throw new Exception("The value " + val + " cannot be
deleted because it is missing.");
}
RegistryImpl.RegDeleteValue(m_uiHKey, val);
}
/// <summary>
/// Deletes the specified value from this key. The string subKey
is not case sensitive.
/// </summary>
/// <param name="val">Name of the value to delete..</param>
public void DeleteValue(string val)
{
// just call the overloaded function
DeleteValue(val, false);
}
/// <summary>
/// Retrieves the count of subkeys at the base level, for the current
key.
/// </summary>
public int SubKeyCount
{
get
{
AssertIsOpen();
int Subkeys = 0;
int nullStuff = 0;
char[] test = null;
// query the registry key for the number of subkeys
int retVal =
RegistryImpl.RegQueryInfoKey(m_uiHKey, test, ref nullStuff,
0, ref Subkeys, ref nullStuff, ref nullStuff,
ref nullStuff, ref nullStuff,
ref nullStuff, 0, 0);
return Subkeys;
}
}
/// <summary>
/// Retrieves an array of strings that contains all the subkey names.
/// </summary>
/// <returns>An array of strings that contains the names of the subkeys
for the current key.</returns>
public string[] GetSubKeyNames()
{
AssertIsOpen();
// create an arraylist to temporarily hold our subkey names
ArrayList subKeyNames = new ArrayList();
int nullStuff = 0;
int iMaxSubKeyLen = 255;
char[] chNull = null;
int iSubKeyLen = 0;
char[] chSubKeyName = new char[iMaxSubKeyLen];
for (int x = 0; x < SubKeyCount; x++)
{
// call RegEnumKeyEx for as many subkeys there are
iSubKeyLen = iMaxSubKeyLen;
RegistryImpl.RegEnumKeyEx(m_uiHKey, x, chSubKeyName, ref
iSubKeyLen, 0, chNull, ref nullStuff, 0);
subKeyNames.Add(new string(chSubKeyName, 0, iSubKeyLen));
}
// return the array as a string Array
return (string[])subKeyNames.ToArray(typeof(string));
}
/// <summary>
/// Retrieves the count of values in the key.
/// </summary>
public int ValueCount
{
get
{
AssertIsOpen();
int icValueKeys = 0;
int nullStuff = 0;
char[] test = null;
// query the registry for the number of values in the current
key.
int retVal =
RegistryImpl.RegQueryInfoKey(m_uiHKey, test, ref nullStuff,
0, ref nullStuff, ref nullStuff, ref nullStuff,
ref icValueKeys, ref nullStuff,
ref nullStuff, 0, 0);
return icValueKeys;
}
}
/// <summary>
/// Retrieves an array of strings that contains all the value names
associated with this key.
/// </summary>
/// <returns>An array of strings that contains the value names for
the current key.</returns>
public string[] GetValueNames()
{
AssertIsOpen();
// array list to temporarily hold the names of the values
ArrayList valueNames = new ArrayList();
int iMaxValueNameLen = 255;
byte[] byData = null;
int iDataLen = 0;
int iType = 0;
int iValueNameLen = 0;
char[] chValueName = new char[iMaxValueNameLen];
for (int x = 0; x < ValueCount; x++)
{
// call RegEnumKeyEx for all the values in the
iValueNameLen = iMaxValueNameLen;
RegistryImpl.RegEnumValue(m_uiHKey, x, chValueName, ref iValueNameLen,
0, ref iType, ref byData, ref iDataLen);
valueNames.Add(new string(chValueName, 0, iValueNameLen));
}
return (string[])valueNames.ToArray(typeof(string));
}
/// <summary>
/// Retrieves the specified value, or the default value you provide
if the specified value is not found.
/// </summary>
/// <param name="val">Name of the value to retrieve.</param>
/// <param name="initialValue">Value to return if name does not exist.</param>
/// <returns>The data associated with name, or defaultValue if name
is not found.</returns>
public object GetValue(string val, object initialValue)
{
AssertIsOpen();
int iType = 0;
int icData = 0;
byte[] byData = null;
// read in the value information, if no value exists, just return
the initial value specified
if (RegistryImpl.RegQueryValueEx(m_uiHKey, val, 0, ref iType,
byData, ref icData) != 0)
return initialValue;
byData = new byte[icData];
if (RegistryImpl.RegQueryValueEx(m_uiHKey, val, 0, ref iType,
byData, ref icData) != 0)
return initialValue;
// Switch the type we have, and convert to the proper type
switch (iType)
{
case RegistryImpl.REG_BINARY:
return byData;
case RegistryImpl.REG_DWORD:
return BitConverter.ToInt32(byData, 0);
case RegistryImpl.REG_SZ:
return UnicodeEncoding.Unicode.GetString(byData, 0, icData);
case RegistryImpl.REG_EXPAND_SZ:
return UnicodeEncoding.Unicode.GetString(byData, 0, icData);
default:
throw new Exception("Unknown registry type!");
}
}
/// <summary>
/// Retrieves the data associated with the specified value, or null
if the value does not exist.
/// </summary>
/// <param name="val">Name of the value to retrieve.</param>
/// <returns>The data associated with name , or null if the value
does not exist.</returns>
public object GetValue(string val)
{
// just call the overloaded function
return GetValue(val, null);
}
/// <summary>
/// Sets the specified value. The string subKey is not case sensitive.
/// </summary>
/// <param name="valName">Name of value to store data in.</param>
/// <param name="valData">Data to store.</param>
public void SetValue(string valName, object valData)
{
AssertIsOpen();
// find out what type of data we are setting, and call the appropriate
RegSetValueEx function
if (valData is string)
{
char[] chData = ((string)valData).ToCharArray();
byte[] byValData = new byte[UnicodeEncoding.Unicode.GetByteCount(chData)
+ 1];
byValData = UnicodeEncoding.Unicode.GetBytes(chData);
byValData[byValData.GetUpperBound(0)] = 0;
RegistryImpl.RegSetValueEx(m_uiHKey, valName, 0, RegistryImpl.REG_SZ,
byValData, byValData.GetLength(0));
}
else if (valData is byte[])
{
RegistryImpl.RegSetValueEx(m_uiHKey, valName, 0, RegistryImpl.REG_BINARY,
(byte[])valData,
((byte[])valData).GetLength(0));
}
else if (valData is int)
{
byte[] byValData = BitConverter.GetBytes((int)valData);
RegistryImpl.RegSetValueEx(m_uiHKey, valName, 0, RegistryImpl.REG_DWORD,
byValData, byValData.GetLength(0));
}
else
throw new Exception("Unknown type to set!");
}
/// <summary>
/// Retrieves a specified subkey.
/// </summary>
/// <param name="subkey">Name or path of subkey to open.</param>
/// <param name="writeable">Set to true if you need write access
to the key.</param>
/// <returns>The subkey requested, or null if the operation failed.</returns>
public RegistryKey OpenSubKey(string subkey, bool writeable)
{
AssertIsOpen();
uint uiSubHKey = RegistryImpl.OpenKey(m_uiHKey, subkey);
RegistryKey rk = new RegistryKey(uiSubHKey, subkey);
rk.m_bReadOnly = !writeable;
return rk;
}
/// <summary>
/// Retrieves a subkey as read-only.
/// </summary>
/// <param name="subkey">Name or path of subkey to open.</param>
/// <returns>The subkey requested, or null if the operation failed.</returns>
public RegistryKey OpenSubKey(string subkey)
{
// just call the overloaded function
return OpenSubKey(subkey, false);
}
/// <summary>
/// Retrieves the name of the key.
/// </summary>
public string Name
{
get { return m_sName; }
}
#region Implementation of IDisposable
public void Dispose()
{
Close();
}
#endregion
private void AssertIsOpen()
{
if (m_uiHKey == 0)
throw new IOException("The RegistryKey on which this method
is being invoked is closed");
}
/// <summary>
/// Retrieves a string representation of this key.
/// </summary>
/// <returns>A string representing the key. If the specified key
is invalid (cannot be found) then a null value is returned.</returns>
public override string ToString()
{
return Name;
}
}
/// <summary>
/// This class holds root RegistryKeys for the system registry.
/// Use these keys to manipulate the registry.
/// </summary>
public sealed class Registry
{
private static RegistryKey m_CurrentUser =
new RegistryKey((uint)RegistryImpl.RootKey.HKEY_CURRENT_USER,
"HKEY_CURRENT_USER");
private static RegistryKey m_Users = new RegistryKey((uint)RegistryImpl.RootKey.HKEY_USERS,
"HKEY_USERS");
private static RegistryKey m_LocalMachine =
new RegistryKey((uint)RegistryImpl.RootKey.HKEY_LOCAL_MACHINE,
"HKEY_LOCAL_MACHINE");
private static RegistryKey m_ClassesRoot =
new RegistryKey((uint)RegistryImpl.RootKey.HKEY_CLASSES_ROOT,
"HKEY_CLASSES_ROOT");
public static RegistryKey CurrentUser
{
get { return m_CurrentUser; }
}
public static RegistryKey Users
{
get { return m_Users; }
}
public static RegistryKey LocalMachine
{
get { return m_LocalMachine; }
}
public static RegistryKey ClassesRoot
{
get { return m_ClassesRoot; }
}
}
/// <summary>
/// Internal helper class for registry access.
/// </summary>
public class RegistryImpl
{
public enum RootKey : uint
{
HKEY_CLASSES_ROOT = 0x80000000,
HKEY_CURRENT_USER = 0x80000001,
HKEY_LOCAL_MACHINE = 0x80000002,
HKEY_USERS = 0x80000003
}
public enum KeyDisposition : int
{
REG_CREATED_NEW_KEY = 1,
REG_OPENED_EXISTING_KEY = 2
}
internal const int REG_SZ = 1;
internal const int REG_EXPAND_SZ = 2;
internal const int REG_BINARY = 3;
internal const int REG_DWORD = 4;
#region DLL Imports
[DllImport("coredll.dll", EntryPoint = "RegOpenKeyEx")]
public static extern int RegOpenKeyEx(uint hKey, string lpSubKey,
int ulOptions, int samDesired, ref uint phkResult);
[DllImport("coredll", EntryPoint = "RegCreateKeyEx")]
public static extern int RegCreateKeyEx(uint hKey, string lpSubKey,
int lpReserved, string lpClass, int dwOptions,
int samDesired, ref int lpSecurityAttributes,
ref uint phkResult,
ref int lpdwDisposition);
[DllImport("coredll.dll", EntryPoint = "RegEnumKeyEx")]
public static extern int RegEnumKeyEx(uint hKey, int iIndex, char[]
sKeyName,
ref int iKeyNameLen, int iReservedZero,
char[] sClassName, ref int iClassNameLen,
int iFiletimeZero);
[DllImport("coredll.dll", EntryPoint = "RegEnumValue")]
public static extern int RegEnumValue(uint hKey, int iIndex, char[]
sValueName,
ref int iValueNameLen, int
iReservedZero, ref int iType, ref byte[] byData,
ref int iDataLen);
[DllImport("coredll.dll", EntryPoint = "RegQueryInfoKey")]
public static extern int RegQueryInfoKey(uint hKey, char[] lpClass,
ref int lpcbClass,
int reservedZero, ref int
cSubkey, ref int iMaxSubkeyLen,
ref int lpcbMaxSubkeyClassLen,
ref int cValueNames, ref
int iMaxValueNameLen, ref int iMaxValueLen,
int securityDescriptorZero,
int lastWriteTimeZero);
[DllImport("coredll.dll", EntryPoint = "RegQueryValueEx")]
public static extern int RegQueryValueEx(uint hKey, string lpValueName,
int lpReserved, ref int lpType, byte[] lpData,
ref int lpcbData);
[DllImport("coredll.dll", EntryPoint = "RegSetValueExW")]
public static extern int RegSetValueEx(uint hKey, string lpValueName,
int lpReserved, int lpType, byte[] lpData,
int lpcbData);
[DllImport("coredll.dll", EntryPoint = "RegCloseKey")]
public static extern int RegCloseKey(uint hKey);
[DllImport("coredll.dll", EntryPoint = "RegDeleteKey")]
public static extern int RegDeleteKey(uint hKey, string keyName);
[DllImport("coredll.dll", EntryPoint = "RegDeleteValue")]
public static extern int RegDeleteValue(uint hKey, string valueName);
#endregion
/// <summary>
/// Helper to allow me to easily open a key
/// </summary>
/// <param name="RootKey"></param>
/// <param name="SubKey"></param>
/// <returns></returns>
public static uint OpenKey(uint RootKey, string SubKey)
{
uint hKey = 0;
int ret = 0;
try
{
RegOpenKeyEx(RootKey, SubKey, 0, 0, ref hKey);
}
catch (Exception ex)
{
Console.WriteLine("Exception opening key: " + ex.Message);
throw;
}
if (ret != 0)
Console.WriteLine("Failed to open key: " + ret.ToString());
return hKey;
}
/// <summary>
/// Helper to allow me to easily Create a key
/// </summary>
/// <param name="RootKey"></param>
/// <param name="SubKey"></param>
/// <param name="KeyClass"></param>
/// <param name="Disposition"></param>
/// <returns></returns>
public static uint CreateKey(uint RootKey, string SubKey, string
KeyClass, ref KeyDisposition Disposition)
{
uint hKey = 0;
int disp = 0;
int reserved = 0;
int ret = 0;
try
{
ret = RegCreateKeyEx(RootKey, SubKey, 0, KeyClass, 0, 0,
ref reserved, ref hKey, ref disp);
}
catch (Exception ex)
{
Console.WriteLine("Exception creating key: " + ex.Message);
throw;
}
if (ret != 0)
Console.WriteLine("Failed to create key: " + ret.ToString());
else
Disposition = (KeyDisposition)disp;
return hKey;
}
}
Regards,
Christian Resma Helle
http://christian-helle.blogspot.com
Regards,
Christian Resma Helle
http://christian-helle.blogspot.com
Check out these links:
http://www.codeplex.com/ManagedTodayScreen
http://www.christec.co.nz/blog/archives/279
Regards,
Christian Resma Helle
http://christian-helle.blogspot.com
> I am developing application in Windows mobile 6.0, using C# and .NET