我知道这个帖子很旧,但我最近遇到了这个问题,我找到了解决方案。
GetOpenFileName() 将上次使用的路径保存在注册表中。路径是:
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\
有两个键,我不确定实际使用的是哪个以及在什么情况下,但我从它们中删除了我的应用程序条目。两个关键是:
"LastVisitedPidlMRU" 和 "LastVisitedPidlMRULegacy"。
应用程序名称保存为 16 位字符编码的 RegBinary 值(这就是它不会出现在注册表搜索中的原因...)。
我想出了以下函数来删除注册表项,迫使 Windows 相信 GetOpenFileName() 以前从未被我的应用程序调用过:
void clear_path_in_registry ()
{
char keypath[PATH_MAX];
char *keys[] = { "LastVisitedPidlMRU", "LastVisitedPidlMRULegacy" };
#define NO_OF_KEYS (sizeof(keys)/sizeof(*keys))
int keynr;
HKEY hkey;
int res;
char val_data[BUFLEN];
DWORD val_len, data_len;
int i;
char val_name[VALUELEN];
char progname[PATH_MAX];
char *p, *q;
char exename[PATH_MAX];
int index;
int *pi , *pj;
do_debug (1, "clear_path_in_registry()\n");
GetModuleFileName (NULL, progname, sizeof(progname));
p = strrchr (progname, '\\');
if (p)
p ++;
strncpy (exename, p, sizeof(exename)-1);
keynr = 0;
do
{
snprintf (keypath, sizeof(keypath),
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\%s",
keys[keynr]);
res = RegOpenKeyEx (HKEY_CURRENT_USER,keypath,0,KEY_ALL_ACCESS,&hkey);
if (res == ERROR_SUCCESS)
{
i = 0;
val_len = sizeof (val_name);
data_len = sizeof (val_data);
while (RegEnumValue(
hkey,i,val_name,&val_len,NULL,NULL,(BYTE *)val_data,&data_len)
== ERROR_SUCCESS)
{
if (stricmp(val_name, "MRUListEx"))
{
/* is not the "MRUListEx" value -> extract program name
*
* for some (unknown) reason the program names are not stored as
* RegSZ but rather as RegBinary values. They are encoded in some
* dual-byte encoding. In my experiments the high bytes are
* always 0x00; so the transcoding is simple, just skip the high
* bytes. Probably there is a WIN32 API call for this but I did
* dig into that for now ...
*/
p = progname;
q = val_data;
while (*q)
{
*p++ = *q++;
q ++;
}
*p = '\0';
/* the index in the MRUList is the value name */
index = atoi (val_name);
if (stricmp (progname, exename) == 0)
{
/* found the value with current executable name -> delete it */
res = RegDeleteValue (hkey, val_name);
if (res == ERROR_SUCCESS)
{
/* delete the entry from the MRUList
*
* The MRUListEx value is a of the type RegBinary as well.
* The data structure is fairly simple: just 4-byte integers
* one after the other; -1 marks the end of the list
*/
data_len = sizeof (val_data);
res = RegQueryValueEx (hkey, "MRUListEx", NULL, NULL,
(BYTE*)val_data, &data_len);
if (res == ERROR_SUCCESS)
{
pi = (int *)val_data;
pj = (int *)val_data;
while (*pj != -1)
{
if (*pj == index)
{
pj ++;
data_len -= sizeof(int);
}
*pi++ = *pj++;
}
*pi = *pj;
res = RegSetValueEx (hkey, "MRUListEx", 0, REG_BINARY,
(BYTE *)val_data, data_len);
if (res != ERROR_SUCCESS)
{
do_debug (1,"ERROR writing registry value 'MRUListEx'\n");
}
} else
{
do_debug (1, "ERROR reading registry value 'MRUListEx'\n");
}
} else
{
do_debug (1,"ERROR deleting registry value '%s'\n",val_name);
}
}
}
val_len = sizeof (val_name);
data_len = sizeof (val_data);
i ++;
} /* iterate through registry values */
}
res = RegCloseKey (hkey);
if (res != ERROR_SUCCESS)
{
do_debug (1, "Error closing registry key '%s'\n", keys[keynr]);
}
keynr ++;
} while (keynr < NO_OF_KEYS);
}
在调用 GetOpenFileName() 之前调用这个函数就可以了。
我使用 Windows 10,版本 19042.1052,64 位进行了测试。
约翰内斯