3

レジストリ キーを見つけて削除できるスクリプトを探しています。私のキーは「{24EAA2C1-3EE7-40E0-AEA3-D20AA14A6005}」のようなものです。このキーは多くの場所に保存されています。

HKEY_CLASSES_ROOT\CLSID\{MY_KEY}
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{MY_KEY}
HKEY_CURRENT_USER\Software\Classes\CLSID\{MY_KEY}
HKEY_CURRENT_USER\Software\Classes\Wow6432Node\CLSID\{MY_KEY}
HKEY_USERS\S-1-5-21-1786904987-2011555162-1551513139-1001\Software\Classes\CLSID\{MY_KEY}
HKEY_USERS\S-1-5-21-1786904987-2011555162-1551513139-1001\Software\Classes\Wow6432Node\CLSID\{KEY}
HKEY_USERS\S-1-5-21-1786904987-2011555162-1551513139-1001_Classes\CLSID\{MY_KEY}
HKEY_USERS\S-1-5-21-1786904987-2011555162-1551513139-1001_Classes\Wow6432Node\CLSID\{MY_KEY}

ただし、これらの場所は異なる場合があります (削除する前にそれらを見つけなければならないのはそのためです)。(コンソール アプリケーションで) C# スクリプトを使用して、このキーの出現ごとに削除したいと思います。

私はこれを試しました:

static void Main(string[] args)
{
    DeleteKeyTest("{MY_KEY}");
}

private RegistryKey baseRegistryKey = Registry.ClassesRoot;
public void DeleteKeyTest(string KeyName)
{
    try
    {
        RegistryKey rk = baseRegistryKey;
        rk.DeleteSubKey(KeyName);       
    }
    catch (Exception e)
    {
    }
}

エラーが発生します:

サブキーが存在しないため、サブキーを削除できません。

編集

キーのすべての出現を見つけるために使用される私のコードは次のとおりです。

public List<string> SearchKey(string Key)
{
    List<string> ListKeys = getKeyPath(Key, RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64));
    ListKeys.AddRange(getKeyPath(Key, RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)));
    ListKeys.AddRange(getKeyPath(Key, RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)));
    ListKeys.AddRange(getKeyPath(Key, RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Registry64)));
    ListKeys.AddRange(getKeyPath(Key, RegistryKey.OpenBaseKey(RegistryHive.CurrentConfig, RegistryView.Registry64)));
    return ListKeys;
}

private List<string> getKeyPath(string key, RegistryKey registryKey)
{
    List<string> keys = new List<string>();
    if (CanReadRegistryKey(registryKey))
    {
        foreach (string keyname in registryKey.GetSubKeyNames())
        {
            if (keyname.Contains(key))
                keys.Add(registryKey.Name + "\\" + keyname);

            if (CanReadKey(registryKey, keyname))
                keys.AddRange(getKeyPath(key, registryKey.OpenSubKey(keyname, RegistryKeyPermissionCheck.ReadSubTree)));
        }
    }
    return keys;
}

private bool CanReadRegistryKey(RegistryKey registryKey)
{
    try
    {
        registryKey.GetSubKeyNames();
        return true;
    }
    catch (UnauthorizedAccessException e)
    {
        return false;
    }
}

private bool CanReadKey(RegistryKey registryKey, string keyname)
{
    try
    {
        registryKey.OpenSubKey(keyname, RegistryKeyPermissionCheck.ReadSubTree);
        return true;
    }
    catch (SecurityException e)
    {
        return false;
    }
}

使用法 :

List<string> ListKeys = SearchKey("MY_KEY");

いつも同じ結果が得られるとは限りません。7 つのキーが見つかることもあれば、8 つのキーが見つかることもあります (見つからないキーは HKEY_CLASSES_ROOT\Wow6432Node\CLSID{MY_KEY} です)。

削除するための私のコードは次のとおりです。

public int RemoveKey(string Key)
{
    int count = RemoveKeys(Key, RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64));
    count += RemoveKeys(Key, RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64));
    count += RemoveKeys(Key, RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64));
    count += RemoveKeys(Key, RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Registry64));
    count += RemoveKeys(Key, RegistryKey.OpenBaseKey(RegistryHive.CurrentConfig, RegistryView.Registry64));
    return count;
}

private int RemoveKeys(string key, RegistryKey registryKey)
{
    int count = 0;
    if (CanReadRegistryKey(registryKey))
    {
        foreach (string keyname in registryKey.GetSubKeyNames())
        {
            count += RemoveKeys(key, registryKey.OpenSubKey(keyname));
            try
            {
                if (keyname.Contains(key))
                {
                    registryKey.DeleteValue(keyname);
                    count++;
                }
            }
            catch (Exception e)
            {
            }
        }
    }
    return count;
}

使用法 :

int NumberOfRemovedKeys = RemoveKey("MY_KEY");

しかし、私はいつもこのコードでエラーを受け取りました:

registryKey.DeleteValue(keyname);

エラーメッセージ :

System.UnauthorizedAccessException: レジストリ キーに書き込めません。

管理者モードでアプリケーションを起動しようとすると、同じエラーが発生しました。しかし、regedit から手動でキーを削除しようとすると、問題はありません。

「検索」コードで、フルパスを含むキーのリストを取得しました。完全パスを使用してキーを直接削除しようとしましたが、RegistryHive (たとえば RegistryHive.ClassesRoot) を使用して RegistryKey を初期化する必要があるため不可能ですが、RegistryHive は既に完全パスにあります。

削除の許可を得るにはどうすればよいですか?

4

2 に答える 2