〜 システム 〜
レジストリの項目を削除 (要ADVAPI32.DLL)

今回はAPI関数RegDeleteValueにハイブ(メインキー・サブキー・名前のセット)を指定して、
キーはそのままで「項目の名前」と「項目の値」のセットを削除します。
レジストリエディタ(Regedit.exe)を見ると左側ペインのツリービューに以下5種類の「メインキー」

HKEY_CLASSES_ROOT(=0x80000000)」  拡張子や関連付け等のファイルそのものに関するキー。通称「HKCR」。 「HKEY_CURRENT_USER(=0x80000001)」  字の如く、現在のログインユーザーに関するキー。通称「HKCU」。 「HKEY_LOCAL_MACHINE(=0x80000002)」  全ユーザー共通のシステム全体の設定に関するキー。通称「HKLM」。 「HKEY_USERS(=0x80000003)」  ウィンドウズの初期情報とユーザー毎の設定に関するキー。通称「HKU」。 「HKEY_CURRENT_CONFIG(=0x80000005)」  現在のシステム設定に関するキー。通称「HKCC」。

ツリーを開くと幾つもぶら下がっている「サブキー」 選択したサブキー右側ペインのリストビューに一覧で表示される項目「名前」と、 タイプ「種類」と項目値「データ」が表示されます。 API関数の第1引数は対象キーのハンドルを指定しますので、 当関数実行の前にコチラで紹介した「ハンドルを取得する関数」を実行します。 第2引数に値の名前…つまり、項目名を指定します。 コレらを指定し、削除に成功すると0が、失敗するとエラーコードが返りますが、 削除するキーハンドル(サブキー)が正常であって、項目名だけが不正である場合は削除失敗ではなく、 項目名が空文字(="")かNULL(=0)の場合は、名前なし(既定)の項目値が削除されます。 削除に失敗するのは主にサブキー自体が存在しない時や、 サブキー及び項目名は合っているがKEY_SET_VALUE(=0x0002)アクセス権がない時です。 サンプルは、ファイル選択ダイアログの「過去に選択されたパス」履歴なので削除しても問題ありませんが、 その他のレジストリ項目の中には重要なものもあるので、細心の注意を払って処理してください。 当然ですが、如何なる問題が発生しようとも当方は責任を負いません

gethkey キー文字列
キー文字列 定義済キー文字列を指定するとメインキーの定義値を返し、
以下の数値文字列を指定すれば定義済キー文字列を返す。
"0"HKEY_CLASSES_ROOT
"1"HKEY_CURRENT_USER
"2"HKEY_LOCAL_MACHINE
"3"HKEY_USERS
"4"HKEY_PERFORMANCE_DATA
"5"HKEY_CURRENT_CONFIG
"6"HKEY_DYN_DATA

regopenkey 受取変数, キー文字列, アクセスマスク
受取変数開く対象のキーハンドル受取先変数を指定する。
尚、オープン成功なら0、失敗ならエラーコードがstatに代入される。
キー文字列オープンするキーのパス(メインキー+サブキー)を指定する。
アクセスマスク以下に示すキーのセキュリティ権を指定する。
0x0001サブキーデータの問い合わせを許可
0x0002サブキーデータの問い合わせを許可
0x0004サブキーの作成を許可
0x0008サブキーの列挙を許可
0x0010変更の通知を許可
0x0020シンボリックリンクの作成を許可
0x00020006読込系の処理を許可
0x00020019書込系の処理を許可
0x000F003F全ての処理を許可

regsetstr 項目名, データ, キーハンドル, タイプフラグ
項目名 値の名前文字列を指定する。
尚、設定成功すれば0、失敗すればエラーコードがstatに代入される。
データ設定するデータを入れた文字列定数または文字列型変数を指定する。
キーハンドルregopenkey命令で取得した対象キーのハンドルを指定する。
タイプフラグデータの型を下記から指定する。尚、省略すると通常の文字列(=1)となる。
1NULLで終わる文字列
2展開前の環境変数への参照が入った文字列
3バイナリーデータ
432ビット数値(リトルエンディアン形式)
532ビット数値(ビッグエンディアン形式)
6Unicodeシンボリックリンク
7NULLで終わる複数行文字列
8デバイスドライバのリソースリスト
1164ビット数値(リトルエンディアン形式)

regdelvalue キーハンドル, 項目名
キーハンドルregopenkey命令で取得した削除対象キーのハンドルを指定する。
項目名 値の名前文字列を指定する。
尚、削除成功すれば0、失敗すればエラーコードがstatに代入される。

regclose キーハンドル
キーハンドル使い終わって解放する、または設定し終えて更新するキーハンドルを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	ll_libload advapi, "advapi32.dll"
	ll_getproc RegOpenKeyEx, "RegOpenKeyExA", advapi
	ll_getproc RegQueryValueEx, "RegQueryValueExA", advapi
	ll_getproc RegSetValueEx, "RegSetValueExA", advapi
	ll_getproc RegDeleteValue, "RegDeleteValueA", advapi
	ll_getproc RegCloseKey, "RegCloseKey", advapi

#module
#deffunc gethkey str
	mref string, 32
	sdim s, 22, 7
	mref stt, 64
	mref rstr, 65
	s.0 = "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS"
	s.4 = "HKEY_PERFORMANCE_DATA", "HKEY_CURRENT_CONFIG", "HKEY_DYN_DATA"
	strmid rstr, string, 0, 1
	if rstr ! "H" {
		i = 0 + rstr
		rstr = s.i
		return
	}
	instr i, string, "\\"
	if i ! -1 : strmid rstr, string, 0, i : else : rstr = string
	stt = 0
	repeat 7
		if s.cnt = rstr {
			stt = 0x80000000 + cnt
			instr i.0, string, "\\"
			strlen i.1, string
			strmid rstr, string, i + 1, i.1 - i.0 - 1
			break
		}
	loop
	return

#deffunc regopenkey val, str, int
	mref hkey, 16 : mref path, 33 : mref sa, 3
	mref stt, 64
	gethkey path
	if stat = 0 : return
	path = refstr
	prm = stat, 0, 0, (sa = 0) * 0x000F003F + sa
	ll_getptr path : ll_ret prm.1
	ll_getptr hkey : ll_ret prm.4
	ll_callfunc prm, 5, RegOpenKeyEx@
	ll_ret prm : stt = prm
	return

#deffunc reggetvalue val, str ,int, int
	mref data, 24 : mref name, 33 : mref hkey, 2 : mref type, 3
	mref stt, 64
	prm = hkey
	i.1 = 256
	ll_getptr name : ll_ret prm.1
	ll_getptr i    : ll_ret prm.3
	ll_getptr data : ll_ret prm.4
	ll_getptr i.1  : ll_ret prm.5
	ll_callfunc prm, 6, RegQueryValueEx@
	ll_ret prm : stt = prm
	if i >= 4 & (i <= 6) | (i = 11) | (type ! 0) : mref data, 16 // 強制的に数値型に変換
	if type : data = i
	return

#deffunc regsetstr str, str, int, int
	mref name, 32 : mref data, 33 : mref hkey, 2 : mref type, 3
	mref stt, 64
	strlen i, data
	if type ! 3 : i++
	prm = hkey, 0, 0, (type = 0) * 1 + type, 0, i
	ll_getptr name : ll_ret prm.1
	ll_getptr data : ll_ret prm.4
	ll_callfunc prm, 6, RegSetValueEx@
	ll_ret prm : stt = prm
	return

#deffunc regdelvalue int, str
	mref hkey, 0 : mref name, 33
	mref stt, 64
	prm = hkey
	ll_getptr name : ll_ret prm.1
	ll_callfunc prm, 2, RegDeleteValue@
	ll_ret prm : stt = prm
	return

#deffunc regclose int
	mref hkey, 0
	ll_callfunc hkey, 1, RegCloseKey@
	return
#global

	sdim dat, 16
	sdim value, 128
	sdim path, 128
	delnum = 3 // 削除する項目数
	kakucyoushi = "zip" // 削除する拡張子
	listvalue = "MRUList" // 削除項目リスト
	gethkey "1"
	path = refstr + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU\\" + kakucyoushi
	regopenkey key, path
	if stat {
		dialog "[ " + path + " ]が存在しません", 1
	} else {
		mes "1.現在の履歴は[ファイル名(N):]のコンボボックス下矢印を押して確認してください"
		mes "2.[キャンセル]ボタンを押してください([開く]ボタンを押してもいいけど)"
		dialog kakucyoushi, 16
		gosub *deletevalues
		regclose key
	}
	end

*deletevalues
	reggetvalue dat, listvalue, key
	if stat {
		dialog "[ " + listvalue + " ]が存在しません", 1
	} else {
		strlen i, dat
		if i = 0 {
			dialog "[ " + path + " ]は全て削除されています"
		} else {
			mes "- - - - - - - - - -"
			repeat i
				strmid listname, dat, 0, 1
				reggetvalue value, listname, key
				if stat = 0 {
					regdelvalue key, listname // 項目を削除
					if stat = 0 {
						mes "[ " + value + " ]を削除しました"
					} else {
						mes "[ " + value + " ]の削除に失敗しました"
					}
				} else {
					mes "[ " + listname + " ]の値が存在しません"
				}
				strmid dat, dat, 1, i - 1
				if cnt + 1 >= delnum : break
			loop
			regsetstr listvalue, dat, key // 削除項目リストを更新
			dialog "上位" + delnum + "つの項目名と値のセットを削除しました"
		}
	}
	return

定義済情報 = gethkey(キー文字列)
定義済情報定義済情報の受取先を指定する。
キー文字列 定義済キー文字列を指定するとメインキーの定義値を返し、
以下の数値文字列を指定すれば定義済キー文字列を返す。
"0"HKEY_CLASSES_ROOT
"1"HKEY_CURRENT_USER
"2"HKEY_LOCAL_MACHINE
"3"HKEY_USERS
"4"HKEY_PERFORMANCE_DATA
"5"HKEY_CURRENT_CONFIG
"6"HKEY_DYN_DATA

エラーコード = regopenkey(受取変数, キー文字列, アクセスマスク)
エラーコードオープン成功(=0)したか失敗(=エラーコード)したかの状態受取先を指定する。
受取変数開く対象のキーハンドル受取先変数を指定する。
キー文字列オープンするキーのパス(メインキー+サブキー)を指定する。
アクセスマスク以下に示すキーのセキュリティ権を指定する。
0x0001サブキーデータの問い合わせを許可
0x0002サブキーデータの問い合わせを許可
0x0004サブキーの作成を許可
0x0008サブキーの列挙を許可
0x0010変更の通知を許可
0x0020シンボリックリンクの作成を許可
0x00020006読込系の処理を許可
0x00020019書込系の処理を許可
0x000F003F全ての処理を許可

regsetvalue キーハンドル, 項目名, データ, タイプフラグ
キーハンドル regopenkey命令で取得した対象キーのハンドルを指定する。
尚、設定に成功(=0)したか失敗(=エラーコード)したかの状態がstatに返る。
項目名値の名前文字列を指定する。
データ設定するデータを入れた変数を指定する。
タイプフラグデータの型を下記から指定する。尚、省略すると通常の文字列(=1)となる。
1NULLで終わる文字列
2展開前の環境変数への参照が入った文字列
3バイナリーデータ
432ビット数値(リトルエンディアン形式)
532ビット数値(ビッグエンディアン形式)
6Unicodeシンボリックリンク
7NULLで終わる複数行文字列
8デバイスドライバのリソースリスト
1164ビット数値(リトルエンディアン形式)

regdelvalue キーハンドル, 項目名
キーハンドルregopenkey命令で取得した削除対象キーのハンドルを指定する。
項目名 値の名前文字列を指定する。
尚、削除成功すれば0、失敗すればエラーコードがstatに代入される。

regclose キーハンドル
キーハンドル使い終わって解放する、または設定し終えて更新するキーハンドルを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#uselib "advapi32.dll"
#cfunc global RegOpenKeyEx "RegOpenKeyExA" int, sptr, int, int, var
#cfunc global RegQueryValueEx "RegQueryValueExA" int, sptr, int, var, var, var
#func  global RegSetValueEx "RegSetValueExA" int, sptr, int, int, var, int
#func  global regdelvalue "RegDeleteValueA" int, sptr
#func  global regclose "RegCloseKey" int

#module
#defcfunc gethkey str string, local i, local s
	mref rstr, 65
	s.0 = "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS"
	s.4 = "HKEY_PERFORMANCE_DATA", "HKEY_CURRENT_CONFIG", "HKEY_DYN_DATA"
	rstr = string
	if strmid(rstr, 0, 1) ! "H" : return s(int(rstr))
	if instr(rstr, , "\\") ! -1 : rstr = strmid(rstr, 0, instr(rstr, , "\\"))
	foreach s
		if s.cnt = rstr {
			i = 0x80000000 + cnt
			rstr = string
			rstr = strmid(rstr, instr(rstr, , "\\") + 1, strlen(rstr) - instr(rstr, , "\\") - 1)
			break
		}
	loop
	return i

#defcfunc regopenkey var hkey, var path, int sa, local s
	return RegOpenKeyEx(int(gethkey(path)), refstr, , (sa = 0) * 0x000F003F + sa, hkey)

#defcfunc reggetvalue var data, int hkey, str name, int type, local i
	i = 256
	i.1 = RegQueryValueEx(hkey, name, , i.2, data, i)
	if type : data = i.2
	return i.1

#deffunc regsetvalue int hkey, str name, var data, int type, local i
	if type = 0 | type = 1 | type = 2 | type = 6 | type = 7 | type = 8 : data = str(data) : i = strlen(data) + 1
	if type = 4 | type = 5 : data = int(data) : i = 4
	if type = 3 : i = strlen(str(data))
	if type = 11 : i = 8
	RegSetValueEx hkey, name, , (type = 0) * 1 + type, data, i
	return
#global

	sdim dat, 16
	sdim value, 128
	delnum = 3 // 削除する項目数
	kakucyoushi = "*" // 削除する拡張子
	listvalue = "MRUList" // 削除項目リスト
	path = gethkey("1") + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU\\" + kakucyoushi
	if regopenkey(key, path) {
		dialog "[ " + path + " ]が存在しません", 1
	} else {
		mes "1.現在の履歴は[ファイル名(N):]のコンボボックス下矢印を押して確認してください"
		mes "2.[キャンセル]ボタンを押してください([開く]ボタンを押してもいいけど)"
		dialog kakucyoushi, 16
		gosub *deletevalues
		regclose key
	}
	end

*deletevalues
	if reggetvalue(dat, key, listvalue) {
		dialog "[ " + listvalue + " ]が存在しません", 1
	} else {
		if strlen(dat) = 0 {
			dialog "[ " + path + " ]は全て削除されています"
		} else {
			mes "- - - - - - - - - -"
			repeat strlen(dat)
				if reggetvalue(value, key, strmid(dat, 0, 1)) = 0 {
					regdelvalue key, strmid(dat, 0, 1) // 項目を削除
					if stat = 0 {
						mes "[ " + value + " ]を削除しました"
					} else {
						mes "[ " + value + " ]の削除に失敗しました"
					}
				} else {
					mes "[ " + strmid(dat, cnt, 1) + " ]の値が存在しません"
				}
				dat = strmid(dat, 1, strlen(dat) - 1)
				if cnt + 1 >= delnum : break
			loop
			regsetvalue key, listvalue, dat // 削除項目リストを更新
			dialog "上位" + delnum + "つの項目名と値のセットを削除しました"
		}
	}
	return