ImageMagick: win7 | win8 & uac (用户帐户控制) 注册表的一些事
现在用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
ImageMagick: win7 | win8 & uac (用户帐户控制) 注册表的一些事的更多相关文章
- 用户“*****”不具有所需的权限。请验证授予了足够的权限并且解决了 Windows 用户帐户控制(UAC)限制问题。
错误: 用户“ts\***”不具有所需的权限.请验证授予了足够的权限并且解决了 Windows 用户帐户控制(UAC)限制问题. 解决: 当从客户端用IE连接http://xxx.xxx.xxx.xx ...
- BAT-把当前用户以管理员权限运行(用户帐户控制:用于内置管理员帐户的管理员批准模式)
相关资料: http://jingyan.baidu.com/article/72ee561a5dc24fe16138df95.html 网友求助:联想Y400,Win8系统 怎样获得管理员身份 要求 ...
- 浅谈Windows用户帐户控制(User Account Control,UAC)
Microsoft一个事实:大多数用户都用一个Administrator(管理员)帐户来登录Windows.利用这个帐户,用户几乎没有任何限制地访问重要的系统资源,因为该帐户被授予很高的权限.一旦用户 ...
- 不出现用户帐户控制-让Win7的用户账户控制(UAC)放过信任的程序
微软有个官方工具 Microsoft Application Compatibility Toolkit: http://www.microsoft.com/downloads/details.asp ...
- 用户“Michael-PC\Michael”不具有所需的权限。请验证授予了足够的权限并且解决了 Windows 用户帐户控制(UAC)限制问题。
解决方法:在注册表增加键值 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System] 新建-选择“D ...
- Windows Vista for Developers——第四部分:用户帐号控制(User Account Control,UAC)
作者:Kenny Kerr 翻译:Dflying Chen 原文:http://weblogs.asp.net/kennykerr/archive/2006/09/29/Windows-Vista-f ...
- [内网渗透]Windows中的用户帐户与组账户
0x01 用户帐户 1.1 简介 用户帐户是对计算机用户身份的标识,本地用户帐户.密码存在本地计算机上,只对本机有效,存储在本地安全帐户数据库 SAM 中. 文件路径:C: ...
- linux基础命令--userdel 删除用户帐户和相关文件
描述 userdel命令用于删除用户帐户和相关文件. userdel命令修改系统账户文件,删除所有涉及用户的信息,指定的用户(LOGIN)必须存在. 语法 userdel [options] LOGI ...
- usermod - linux修改用户帐户信息
usermod - 修改用户帐户信息 modify a user account usermod [options] user_name usermod 命令修改系统帐户文件来反映通过命令行指定的变化 ...
随机推荐
- 存储过程中的 SET XACT_ABORT ON 和事务
在存储过程中写SET XACT_ABORT ON 有什么用? SET XACT_ABORT ON是设置事务回滚的!当为ON时,如果你存储中的某个地方出了问题,整个事务中的语句都会回滚为OFF时,只回滚 ...
- python之range()函数、for-in循环和while循环
range()函数和for-in循环 函数原型:range(start, end, scan): 参数含义:start:计数从start开始.默认是从0开始.例如range(5)等价于range(0, ...
- vue实例相关2
vue data中 对象/数组 不为空,即使定义为[]/{} new Vue({ el: '#main', data: { list: [], current: {}, aa:'' } }) cons ...
- WPF中如何调整TabControl的大小,使其跟随Window的大小而改变?
多年不写技术博客,手生的很,也不知道大家都关注什么,最近在研究Wpf及3d模型的展示,碰到很多问题,这个是最后一个问题,写出来小结一下...... WPF中如何调整TabControl的大小,使其跟随 ...
- Atcoder Beginner Contest 118 D-Match Matching(完全背包)
题目链接 题意就是给N根火柴,M个数(M只能是1到9,对应的数字也只能是1到9),只能用这M个出现过的数(但每个数可以随便用多少个,只要火柴够)来拼出一个数字(拼出1,2,3,4,5,6,7,8,9分 ...
- Nginx Tcp四层反向代理
L:117 //nginx反向代理代码 server{ listen ; proxy_pass localhost:; //指向上游服务器 proxy_protocol on; //启用对上游传递协议 ...
- xshell使用rz/sz完成文件上传下载
yum -y install lrzsz 安装lrzsz 使用rz完成文件上传 使用sz完成文件下载
- DRF 视图和路由
Django Rest Feamework 视图和路由 DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个 ...
- 「BZOJ1251」序列终结者 (splay 区间操作)
题面: 1251: 序列终结者 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 5367 Solved: 2323[Submit][Status][D ...
- python_getpass 模块的使用
可以实现输入用户密码的时候隐藏输入显示.更加安全. 默认自带Password: 的提示 如果自己指定提示内容就用自己的替换默认 import getpass passwd = getpass.getp ...