ImageMagick: win7 | win8 & uac (用户帐户控制) 注册表的一些事
2015-06-18 10:02
369 查看
现在用win7,win8的人越来越多了, 程序在一些 win 7, win8 上运行会遇到一些之前没想过的兼容性问题。
比如 64位系统运行32位程序时的注册表重定向,还有因为 uac (用户帐户控制)注册表的重定向等。
ImageMagick 在安装的时候,相关数据写在 HKEY_LOCAL_MACHINE 下面, 这在 xp 系统下,一般不会出什么问题。
但由于在 win7,win8上,由于64位系统或uac的问题,导致注册表的路径重定向, 特别是 uac 问题,要想将数据保存到HKEY_LOCAL_MACHINE 必须要管理员身份运行软件。
经过一天多时间研究,一开始在网上找到一个办法,通过修改 ImageMagick 的环境变量,因为根据ImageMagick的源代码,module.c (537行)
static MagickBooleanType GetMagickModulePath(const char *filename,
MagickModuleType module_type,char *path,ExceptionInfo *exception)
{
char
*module_path;
assert(filename != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
assert(path != (char *) NULL);
assert(exception != (ExceptionInfo *) NULL);
(void) CopyMagickString(path,filename,MaxTextExtent);
module_path=(char *) NULL;
switch (module_type)
{
case MagickImageCoderModule:
default:
{
(void) LogMagickEvent(ModuleEvent,GetMagickModule(),
"Searching for coder module file \"%s\" ...",filename);
module_path = GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");
#if defined(MAGICKCORE_CODER_PATH)
if (module_path == (char *) NULL)
module_path=AcquireString(MAGICKCORE_CODER_PATH);
#endif
一开始,我在程序开头加了一句:putenv("MAGICK_CODER_MODULE_PATH=c:\\imagemagick\\modules\\coders\\"); //设置环境变量
我以为这样设置后,ImageMagick就不会对注册表有依赖了,可谁知:
printf("MAGICK_CODER_MODULE_PATH:%s\n", getenv("MAGICK_CODER_MODULE_PATH")); //在我的程序中能正常显示的路径
但是 GetEnvironmentValue("MAGICK_CODER_MODULE_PATH"); 返回的是 (null)
我查看了 ImageMagick 的源代码,发现 GetEnvironmentValue() 其实调用的就是 putenv()
可为什么返回的是 null ? 测试发现使用 putenv("MAGICK_CODER_MODULE_PATH=..."); 一点用没有。
再继续研究ImageMagick源代码:
module.c (634行)
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
{
const char
*registery_key;
unsigned char
*key_value;
/*
Locate path via registry key.
*/
switch (module_type)
{
case MagickImageCoderModule:
default:
{
registery_key="CoderModulesPath";
break;
}
case MagickImageFilterModule:
{
registery_key="FilterModulesPath";
break;
}
}
key_value=NTRegistryKeyLookup(registery_key);
if (key_value == (unsigned char *) NULL)
{
ThrowMagickException(exception,GetMagickModule(),ConfigureError,
"RegistryKeyLookupFailed","`%s'",registery_key);
return(MagickFalse);
}
-------------------------------------------------------------------------------
nt-base.c (1813行)
MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey)
{
char
package_key[MaxTextExtent];
DWORD
size,
type;
HKEY
registry_key;
LONG
status;
unsigned char
*value;
/*
Look-up base key.
*/
(void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
registry_key=(HKEY) INVALID_HANDLE_VALUE;
status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,®istry_key);
if (status != ERROR_SUCCESS)
status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ,
®istry_key);
if (status != ERROR_SUCCESS)
{
registry_key=(HKEY) INVALID_HANDLE_VALUE;
return((unsigned char *) NULL);
}
-------------------------------------------------------------------------------------
原来 ImageMagick 搜索注册表的路径有个顺序,先搜索 HKEY_LOCAL_MACHINE, 再搜索 HKEY_CURRENT_USER
看到这里,我想到一个办法,由于 uac 的问题导致普通用户无法写入设置 HKEY_LOCAL_MACHINE,但可以设置 HKEY_CURRENT_USER
只需将相关的数据写入到 HKEY_CURRENT_USER, 这样就不需要管理员身份也能正常的运行了。
经过测试,验证了我的这个想法,问题终于解决了,以后不用烦在 win7,win8上的兼容性问题了。
2014-09-19
比如 64位系统运行32位程序时的注册表重定向,还有因为 uac (用户帐户控制)注册表的重定向等。
ImageMagick 在安装的时候,相关数据写在 HKEY_LOCAL_MACHINE 下面, 这在 xp 系统下,一般不会出什么问题。
但由于在 win7,win8上,由于64位系统或uac的问题,导致注册表的路径重定向, 特别是 uac 问题,要想将数据保存到HKEY_LOCAL_MACHINE 必须要管理员身份运行软件。
经过一天多时间研究,一开始在网上找到一个办法,通过修改 ImageMagick 的环境变量,因为根据ImageMagick的源代码,module.c (537行)
static MagickBooleanType GetMagickModulePath(const char *filename,
MagickModuleType module_type,char *path,ExceptionInfo *exception)
{
char
*module_path;
assert(filename != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
assert(path != (char *) NULL);
assert(exception != (ExceptionInfo *) NULL);
(void) CopyMagickString(path,filename,MaxTextExtent);
module_path=(char *) NULL;
switch (module_type)
{
case MagickImageCoderModule:
default:
{
(void) LogMagickEvent(ModuleEvent,GetMagickModule(),
"Searching for coder module file \"%s\" ...",filename);
module_path = GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");
#if defined(MAGICKCORE_CODER_PATH)
if (module_path == (char *) NULL)
module_path=AcquireString(MAGICKCORE_CODER_PATH);
#endif
一开始,我在程序开头加了一句:putenv("MAGICK_CODER_MODULE_PATH=c:\\imagemagick\\modules\\coders\\"); //设置环境变量
我以为这样设置后,ImageMagick就不会对注册表有依赖了,可谁知:
printf("MAGICK_CODER_MODULE_PATH:%s\n", getenv("MAGICK_CODER_MODULE_PATH")); //在我的程序中能正常显示的路径
但是 GetEnvironmentValue("MAGICK_CODER_MODULE_PATH"); 返回的是 (null)
我查看了 ImageMagick 的源代码,发现 GetEnvironmentValue() 其实调用的就是 putenv()
可为什么返回的是 null ? 测试发现使用 putenv("MAGICK_CODER_MODULE_PATH=..."); 一点用没有。
再继续研究ImageMagick源代码:
module.c (634行)
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
{
const char
*registery_key;
unsigned char
*key_value;
/*
Locate path via registry key.
*/
switch (module_type)
{
case MagickImageCoderModule:
default:
{
registery_key="CoderModulesPath";
break;
}
case MagickImageFilterModule:
{
registery_key="FilterModulesPath";
break;
}
}
key_value=NTRegistryKeyLookup(registery_key);
if (key_value == (unsigned char *) NULL)
{
ThrowMagickException(exception,GetMagickModule(),ConfigureError,
"RegistryKeyLookupFailed","`%s'",registery_key);
return(MagickFalse);
}
-------------------------------------------------------------------------------
nt-base.c (1813行)
MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey)
{
char
package_key[MaxTextExtent];
DWORD
size,
type;
HKEY
registry_key;
LONG
status;
unsigned char
*value;
/*
Look-up base key.
*/
(void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
registry_key=(HKEY) INVALID_HANDLE_VALUE;
status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,®istry_key);
if (status != ERROR_SUCCESS)
status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ,
®istry_key);
if (status != ERROR_SUCCESS)
{
registry_key=(HKEY) INVALID_HANDLE_VALUE;
return((unsigned char *) NULL);
}
-------------------------------------------------------------------------------------
原来 ImageMagick 搜索注册表的路径有个顺序,先搜索 HKEY_LOCAL_MACHINE, 再搜索 HKEY_CURRENT_USER
看到这里,我想到一个办法,由于 uac 的问题导致普通用户无法写入设置 HKEY_LOCAL_MACHINE,但可以设置 HKEY_CURRENT_USER
只需将相关的数据写入到 HKEY_CURRENT_USER, 这样就不需要管理员身份也能正常的运行了。
经过测试,验证了我的这个想法,问题终于解决了,以后不用烦在 win7,win8上的兼容性问题了。
2014-09-19
相关文章推荐
- 二分查找法
- 1. Two Sum Ruby
- eclipse maven 导出项目依赖的jar包
- 向流氓软件和流氓网站宣战(菜鸟学堂之手把手系列教程之3
- 大型网站架构体系的演变
- Merge k Sorted Lists
- Linux网络编程——I/O复用函数之epoll
- android反编译
- Tomcat7+eclipse+ JRebel 破解实现热部署
- 向流氓软件和流氓网站宣战(菜鸟学堂之手把手系列教程之4
- -2147220891 (VFW_E_UNSUPPORTED_STREAM) 在 Microsoft.DirectX.AudioVideoPlayback.Video.Open(String f
- 记录:2-Factor Authentication
- poj2656---求一列数中最大数的序数而且在前面输入的更优先
- ImageMagick: 6.8.3 升级到 6.8.9 遇到的问题
- Warning!程序员们小心被技术绑架
- 冲刺第十八天
- windows.onload()与$(document).ready()的区别
- url 转换成ip
- 对象转数组 (用json_encode 和 json_decode(,TRUE)
- Json转换利器Gson之实例一-简单对象转化和带泛型的List转化