计算机系统和方法
技术领域
本申请是发明人Edward S.Miller,Bjorn C.Rettig,GregoryWilson,和Shan Xu于1998年8月14日提交的标题为″一个操作系统的多语言用户接口″的美国专利申请09/134,559号的附加部分。
背景技术
本发明涉及操作系统,更具体的是涉及为切换用户接口语言提供一个有效机制的操作系统。
资源是二进制数据或非二进制数据,例如一个文本文件。在Windows NT和所有其它窗口系列的O/S中,资源是二进制数据。资源数据可以驻留在一个应用的可执行文件内,因而可执行文件是其中含有代码和资源数据的二进制文件。代码所定义的进程可以使用其自己的二进制可执行文件或其它可执行文件中的资源。这种进程使用的资源也可以驻留在诸如纯资源动态链接库(DLL)的纯资源文件中。资源可以是标准的,也可以是用户定义的。一个标准资源中的数据描述了一个图标,光标,菜单,对话框,位图,增强元文件,字体,快捷键列表,消息表项,字符串表项,或版本。用户定义资源包含具体应用所需的任何数据。通过各种不同的方式处理操作系统进程所需的资源。许多这样的资源包含特定于语言的字词,符号,格式化数据,等等。通常,根据用户选择的操作系统安装程序包确定具体的语言。如果软件的语言是英语,则操作系统只会安装英语专用的资源。由于可以把大量语言专用资源复制到硬盘或其它非易失存储器上以覆盖所有语言,所以这种处理是方便的。
由于允许根据需要有效地向存储器加载和卸载资源,所以提供单一语言以供操作系统支持的方式也是方便的。总是有非常多的资源需要驻留在存储器中。为了管理资源的加载和卸载以便在不需要时资源不会不必要地占用存储器,产生需要资源的进程和专用于过程的资源的代码可以被并入相同的二进制文件。当一个过程被调用时,一个包含进程代码和附带资源的二进制文件可以被载入存储器或者可以被进程访问。当进程终止时,这种文件的资源和代码部分被从存储器卸载出来或者不可被访问。这些二进制文件可以是可执行程序,动态链接库(DLL),设备驱动程序,等等。如果包括所有可选的语言资源,则会需要过量的存储器。
一个有关操作系统如何处理这种资源的例子如下所述。首先,一个资源搜索程序,即一个操作系统函数被用来产生一个指向指定资源的信息块的句柄。一个需要资源的进程向搜索程序发送一个资源模块句柄和资源名称,类型或语言ID。后者指定资源由资源模块句柄定义的语言专用资源。搜索程序返回一个指向指定资源的信息块的句柄并且进程可以调用一个资源加载程序把资源放到存储器中。进程向资源加载程序提供资源句柄和资源模块句柄,而资源加载程序将资源放入存储器并且返回一个指向包含资源的存储器块的句柄。于是进程可以使用资源。在向存储器载入资源的进程不再需要该资源,即该进程被终止之后,或者在其它情况需要时,操作系统可以使用其它设备释放存储器。
前面描述的只是一个示例性操作系统中的一种资源访问功能。其它机制可以通过其它方式使资源可被访问,例如将文本消息放在一个输出缓冲区中,通过一个单独的函数调用立即加载资源数据并且返回一个指向资源数据的句柄,等等。这些机制的共同特性是它们在存储器、磁盘文件或其它存储系统中搜寻资源并且使资源可被需要该资源的进程访问。这会导致从磁盘向存储器加载文件或仅仅通过提供句柄或某些其它设备来提供对资源的访问。包含资源的文件(设备或通道)可以和定义请求进程的代码位于相同文件内,也可以位于另一个文件中。而其它文件可以包含代码,也可以是一个纯资源文件。进程不必明确地卸载其不再需要的资源。
由于磁盘存储方式的低成本,在某些情况下会期望一个操作系统的相同安装以对用户透明的方式提供若干种语言的适当资源。然而如下所述,对于一个围绕上述资源管理体系而建立的操作系统,可用于修改操作系统以适应可选语言的选项似乎有较大的问题。
为了提供多语言支持,一个选项可能必须为各个语言提供一组不同的二进制文件。考虑到可能有大约一千个包含一个复杂操作系统中语言专用资源的二进制文件并且可能期望支持许多不同的语言,要安装的二进制文件数量实际上会非常大。除了为用户提供语言选择所需的工作量之外,由于针对各个要支持的语言会复制所有的非语言专用资源,所产生的大量文件中的冗余也会非常地多。不但非语言专用资源会需要复制,复制所有代码部分也需要复制。
另一个选项可以是每当需要不同语言的新用户登录时重新安装操作系统二进制文件。由于会占用大量时间,这个选项是不期望的。
另一个选项可以是在各个二进制文件中提供不同的语言专用资源。由于各个二进制文件会只增加语言专用资源,这个选项可以消除第一个选项的冗余。然而这个选项会需要对各个二进制文件进行重新编码,所以也不是一个上佳的选项。目前是以非常有限的方式完成与此类似的处理。某些二进制文件包含任选的资源,其中根据用户的语言或国家各个资源均是最优的。这些二进制文件的代码部分定义了根据对资源的最优语言的″猜测″访问不同资源的进程。根据某些系统参数设置,例如所选择的日期格式作出这种猜测。所以,如果选择俄国风格的日期格式,则可以加载被标记成俄国的资源。
至少有一种目前以有限方式提供语言选择的操作系统。这个操作系统为各个语言提供单独的文本文件。当一个进程需要某个具体语言的文本文件资源时,操作系统访问适当的文件。用户可以通过一个系统变量选择其缺省语言选择。
如上所述,至少一个当前的操作系统(Windows)为建立语言专用库提供了某些支持,例如文本消息。一个系统变量被定义成指示操作系统安装的地区(注意,一个系统的地区不是一种语言设置。地区是语言和位置的综合),并且这个变量可以被操作系统上运行的应用用来格式化当前语言专用的消息。然而这需要上述进程(应用)精确识别适当的语言资源及其位置。作为一种转换模型,其中需要承担大范围的重新编码工作。
现有技术的操作系统体系还没有哪个提供了建议操作系统以非常自动化的方式提供多语言支持的手段。并且,也没有哪个提出了通过在相同文件中存储代码和资源部分从而保留二进制文件固有的节省空间特性的方法。前面建议的提供期望功能的简单变换显然成本过高并且/或者所需的冗余数据容量过大。任何易于实现的转换无疑将是一种与任何现有技术的系统显著不同的系统。
参照图1,在一个现有技术操作系统的一个公共操作中,加载一个二进制文件20。二进制文件20包含一个代码部分10和一个资源部分30并且可以是操作系统的任何文件单元或由第三方提供的一个文件单元。例如,二进制文件20可以是一个可执行二进制文件,一个动态链接库(DLL),或一个设备驱动程序。资源部分30可以包含代码部分使用的某些资源,特别是代码部分10产生的进程专门需要并且在代码部分10定义的进程不再需要时可以从存储器卸载的那些资源。换言之,资源30是那些会被编码在代码部分10中的进程需要的资源,并且一旦那些进程被终止,则不再需要维护存储器中资源部分30包含的资源。例如,二进制文件10可以是一个核心资源或一个和操作系统一起提供的,诸如外挂文本编辑器的应用。例如对于编辑器,当用户终止编辑器程序时,但不再需要这个文本编辑器所需的资源。包含代码10和资源30的二进制文件20会被从存储器中清除掉。当然,代码部分10可以使用其它文件的其它资源并且也可以使用其它进程。
参照图2,资源85和使用该资源的代码55也可以位于不同的文件25和22中。例如,在一个代码片段50中定义的一个应用55访问的资源85可以被包含在一个纯资源DLL或一个包含代码70和资源60的独立文件25中。应用55可以驻留在一个也包含资源40的文件中。另一个操作系统设备可以被用来根据资源类型和名称搜寻文件。对资源的管理(加载和卸载)可以由资源加载程序来完成。
参照图3,一个进程110使用一个资源加载程序130和一个资源搜索程序135访问资源。资源加载程序是一个提供对资源数据125的访问的操作系统设备,其中资源数据125被指定了一个资源模块句柄和资源句柄。由资源搜索程序产生指示可以在哪里搜寻到根据资源名称指定的资源数据的资源模块句柄。资源名称,类型和一个语言(后者是可选的)被提供给资源搜索程序135,而资源搜索程序135返回一个资源模块句柄。如果资源位于一个不是产生调用进程的模块中,则该模块的句柄必须被提供给资源搜索程序。资源类型可以指定一个位图,活动光标,字体资源,菜单资源,字符串表项等等。
资源加载程序把指定资源加载到存储器中。其中需要一个资源模块句柄和资源句柄。资源模块句柄是其可执行文件包含上述资源的模块。资源句柄标识要加载的资源。资源加载程序130返回一个指向包含与该资源相关的数据的存储器块的句柄。图3中示出的情况与图1或图2中示出的情况是一致的。注意,在涉及Windows APIFindResource和LoadResource的文档中定义了上述函数的例子。还应当注意的是,可以在一个预操作以及如上所述的资源调用的部分操作中加载资源。例如,在Windows操作系统中,一次对LoadLibrary的调用可以导致把一个模块加载到存储器中。
参照图4,其中示出了一个可以在操作系统中访问资源的通用模式。一个进程210使用一个资源处理程序230获得对一个资源数据220的访问。资源处理程序230可以由若干个如参照图3所讨论的,由操作系统提供的不同设备构成。进程通过文件名称,模块250的标识符或某些其它信息向处理程序230标识出所请求的资源并且可以告诉处理程序在哪里能够找到资源。资源处理程序230可能需要将可能被包含在一个模块250中的资源220加载到存储器中,或者需要某些其它使进程210能够访问可访问数据240的装置。进程210被提供一个句柄,地址,指针等等以便访问资源220。图4所描述的进程的重要特性是进程标识所需的资源而操作系统为进程提供对该资源的访问。资源可以驻留在一个磁盘上,该磁盘位于另一个计算机网络连接的上并且通过一个通信端口或任何其他向一个计算机上的进程传送数据的机制来提供。作为请求的一部分,操作系统可以在进程能够访问资源之前向一个不同介质传送资源,例如从磁盘向存储器传送。
一个操作系统方案提供了资源处理部件,上述部件提供了在不需要从请求资源的进程得到任何专门指示的情况下处理多个语言资源的功能。这允许操作系统在使用现有资源和可执行二进制文件的同时以不修改这些构成的方式提供多语言支持。即,允许一个用户选择一种用户接口语言并且资源加载程序会自动将资源调用重定向到适当的资源上。
注意,在后面的所有描述中,向存储器加载数据的概念不能按字面被解释成实际从一个文件取出数据并且把它放到存储器中。在本发明所考虑的操作系统环境中,通过低层操作系统函数完成对物理存储器的实际数据加载。各个进程可以具有一个不与实际物理存储器一致的虚拟存储器空间。在下面的讨论中,当谈及对存储器加载和卸载数据的步骤时,其用意是为了将上述步骤广义地解释成使数据可被进程访问的任何操作系统函数。
从请求资源的角度看,与操作系统设备的交互同处理单个语言的资源的交互是相同的。搜寻资源并且将其返回到一个请求进程的操作系统资源处理部件被加以修改以便动态产生一个到达某个可选语言资源模块的路径。可以根据一个资源标识符和一个由请求资源的进程提供的可选模块句柄来产生路径,并且也可以根据一个指定用户接口的选择语言的,在全系统使用的用户设置来产生路径。使用到可选语言资源的路径取代进程提供的模块句柄。
通过动态产生模块句柄,可以在不对任何固定设施进行修改的情况下扩充操作系统以便将基本模块句柄(被调用进程使用的句柄)与可选语言资源模块关联起来。由于动态产生查找表,因而查找表是为了节约步骤而自动产生的并且从不会过期。当新模块被加到操作系统中时,在没有任何中央数据内务处理的情况下可以增加模块并且可以使用算法产生可选模块句柄。只要新模块名称和现有模块名称之间没有冲突,就可以在不进行任何集中改变的情况下把模块和任何使用该模块的代码或任何包含代码和资源的二进制文件添加到操作系统中。
系统根据需要自动加载和释放可选语言模块,并且这种操作对用户和请求资源的进程是透明的。可选语言资源驻留在各个模块(在最优实现中,如Windows用语所定义的动态链接库或DLL)中,每个模块均由一个路径和模块名称唯一指定如下:
<模块 路径>\mui\<语言_ID>\<模块_名称>
换言之,操作系统从初始模块的加载路径的一个语言专用子目录加载一个可选语言资源模块。通过将相同名称用作调用进程提供的初始模块名称来动态产生路径和模块名称。元素<语言_ID>可以是某些表示语言的紧凑代码。例如,可以是ISO 639语言标准缩写加上一个子语言代号或包含主要和辅助部分的Win32语言标识。
可以根据变化的特征度来请求可选语言。即,可以请求具有某个特征级别的(法国)法语,端士法语或加拿大法语,或者仅仅请求具有某个低特征级别的法语。为了保证产生一个可选语言资源模块句柄的进程的健壮性,算法可以使用多个步骤以便能够使一个具有某特征度的用户接口语言的系统级请求与被提供了另一个特征度的可选语言资源的可用度相一致。例如,假定用户在登录到操作系统时请求端士法语。这规定一个用户变量,该变量要求所有能够遵守要求的进程均应当使用端士法语资源。产生可选语言资源的资源加载程序(或库加载程序)算法应当能够处理只有一个与所请求的语言近似的语言可用的情况。在上述例子中假定只有法语和各种其它可选正统语言可用并且没有确切符合端士法语的语言。期望该算法根据一个请求加载法语可选语言资源,而不是作出某些其它不与系统用户语言ID提出的系统级要求接近的缺省选择。因而,可以象下面那样为算法定义多个近似级别。
首先,算法可以确定在″<模块_路径>\″指定的模块路径中是否存在一个具有等价于当前用户语言ID的标识符,即具有名称″\mui\<语言_ID>\″的子目录。如果这个第一测试失败,则算法可以确定是否存在一个″<模块_路径>\″的子目录,其中该子目录具有一个和对应于当前用户语言ID的正统语言ID等价的标识符,即具有名称″\mui\<正统_语言_ID>\″。如果没有指定系统用户语言ID,则算法可以使用一个代理解析一个子目录,例如使用某些诸如涉及日期或货币格式约定的选项,提示用户的位置的参数选择。可选地,可以调用一个中间语言可选资源模块。其它可以被分配任何期望的优先权的步骤可以从一个缺省的可选语言资源子目录中选择一个替代语言,其中用户语言ID规定的语言不可用但有一个在类似地区平行使用的替代语言。例如,如果在用户语言ID中请求了加拿大法语并且加拿大法语和法语均不可用,但加拿大英语可用,因而可以使用后者。上述根据一个优先权系统选择最优可选资源的过程允许增加可选语言资源的特征度。如果操作系统只配置了唯一的正统语言(例如,英语,但没有英国英语,加拿大英语等等。),则用户可以在后面增加更多的特定语言并且以透明和自动的方式实现用户的选择。
为了提高处理速度,在一个查找表中保存通过动态产生各个可选模块路径而获得的映射。当一个调用进程调用相同资源时,可以通过搜索查找表而不是动态产生路径和句柄的方式获得可选资源模块。注意,通过保存动态产生一个可选资源模块ID的结果,每当请求一个资源时不必重复上述健壮算法的步骤。
另外,产生一个清除表以便产生经过修改的资源加载程序根据系统需求加载和释放存储器。清除表列出了被加载的可选资源模块和请求它们的进程。例如,当请求一个资源的进程被终止时,可以从存储器卸载被终止进程所请求的资源模块。
在一个可选实施例中,通过一个单独目录内的不同文件名而不是通过将不同语言的资源模块放入不同的目录来区分可选语言资源模块。更具体地说,不同的扩展名被加到文件名中以指示资源模块的语言。
注意,操作系统通过在一个加载程序数据列表中产生条目来跟踪被加载和卸载的资源。加载程序数据列表指示需要加载资源模块的进程以便在进程终止或存在其它系统需求时可以卸载这些模块。对于被例如Windows NT中直接使用LoadLibraryEx函数的应用加载的模块,上述资源加载程序可能不″知道″模块的身份。即,没有产生加载程序数据表项。在这种情况下,加载资源模块的程序(例如LoadLibrary)可以查询一个可选语言资源是否存在并且加载该语言资源以取代应用请求的模块。如果应用或进程使用一个产生加载程序数据表项的操作系统程序,则肯定不会加载模块,直到应用或其它进程对资源加载程序发出一个资源请求。
发明内容
本发明提供一种计算机系统,其中包括:对应于多种语言的多个资源模块,每个资源模块均包含对应语言的本地化资源;多个可执行模块,其中至少某些可执行模块包含一个共享资源索引,其中每个共享资源索引均标识一个对应于不同语言的资源模块集合;资源处理器,包括用于从所标识的可执行模块接收本地化资源请求的接收装置,其中,为响应于一个标识某个具有共享资源索引的可执行模块的请求,资源处理器具有:(a)选择装置,用于根据以独立于针对资源处理器的请求的方式获得的一个语言标识符,选择由共享资源索引标识的资源模块集合中的一个资源模块,以及(b)提供装置,用于从所选择的一个资源模块提供所请求的本地化资源。
本发明提供一种计算机系统,其中包括:对应于多种语言的多个资源模块,每个资源模块均包含对应语言的本地化资源;资源处理器,包括用于从所标识的模块接收本地化资源请求的接收装置,其中,为响应于一个标识某个具体模块的请求,资源处理器具有:(a)识别装置,用于识别一个与所标识的可执行模块相关的资源模块集合,(b)选择装置,用于根据以独立于针对资源处理器的请求的方式获得的一个语言标识符,选择资源模块集合中的一个资源模块,和(c)提供装置,用于从选择的一个资源模块而不是所标识的可执行模块提供所请求的本地化资源。
本发明提供一种系统,其中包括:对应于多种语言的多个资源模块,每个资源模块均包含对应语言的本地化资源;多个可执行模块,其中至少某些可执行模块包含一个共享资源索引,每个共享资源索引均标识一个对应于不同语言的资源模块集合;其中共享资源索引包括用于允许一个资源处理器根据以独立于针对资源处理器的请求的方式获得的一个语言标识符从语言专用资源模块中自动提供本地化资源的装置,以及用于从选择的一个资源模块而不是所标识的可执行模块提供所请求的本地化资源。
本发明提供一种提供资源的方法,其中包括:接收一个针对某个所标识的本地化资源的请求,该请求包含一个模块标识;响应于接收到该请求,(a)根据模块标识和以独立于请求的方式获得的一个语言标识符,选择一个资源模块,并且(b)从所选择的资源模块提供所请求的本地化资源,其中选择步骤(a)包括:从模块标识所标识的一个模块获得一个共享资源索引,其中共享资源索引标识对应于不同语言的一个资源模块集合;从资源模块集合中选择一个资源模块,该被选择的资源模块具有使用语言标识符所指示的语言的本地化资源。
根据一个实施例,本发明是一个由操作系统执行的方法。该方法重定向一个调用进程对驻留在一个第一二进制文件中的第一数据的调用。其中执行下列步骤:在一个独立于调用进程的操作用户设置中存储一个语言标识符;当存在一个对应于该语言标识符并且也对应于第一数据或第一二进制文件的一个标识符的第二二进制文件时:(1)根据语言标识符以及第一数据或第一二进制文件动态产生一个到第二二进制文件的路径;(2)在一个将某个标识第一二进制文件的处理模块标识符与一个标识第二二进制文件的可选模块标识符关联起来的查找表中存储该路径;和(3)使第二二进制文件中的一个可选数据而不是第一数据可被调用进程访问。
根据另一个实施例,本发明也是一个由操作系统执行的方法。该方法重定向一个调用进程对驻留在一个包含定义调用进程的可执行代码和资源数据的第一二进制文件中的第一资源数据的调用。在代码中定义调用进程。该方法具有下列步骤:在一个独立于调用进程的变量中存储一个语言标识符;当存在一个对应于该语言标识符并且也对应于第一资源数据或第一二进制文件的第二二进制文件时:(1)根据语言标识符以及第一资源数据或第一二进制文件动态产生一个到第二二进制文件的路径;(2)使第二二进制文件中的一个可选资源数据而不是第一资源数据可被调用进程访问。
根据另一个实施例,本发明是一个向具有访问可执行二进制文件中第一资源数据的功能的操作系统增加多语言能力的方法。该方法包含下列步骤:增加一个可选用户设置以便存储一个选择语言标识符;增加至少一个包含资源数据的可选语言资源文件,其中各个资源数据分别对应于第一资源数据中的相应一个数据;和修改一个资源加载程序以便根据选择语言标识符中存储的一个选定语言把针对各个第一资源数据的调用重定向到可选语言资源数据中的一个对应数据上。
根据一个实施例,本发明是一个由操作系统执行的方法。该方法根据一个调用进程对一个第一数据的调用访问数据。该方法具有下列步骤:确定是否存在一个对应于第一数据的可选语言文件;当确定步骤的结果表明可选语言文件存在时,从可选语言文件向调用进程返回至少一个数据; 当确定步骤的结果表明可选语言文件不存在时,向调用进程返回第一数据。
根据一个实施例,本发明是一个由操作系统执行的方法。该方法重定向一个调用进程对驻留在一个第一二进制文件中的第一数据的调用。其中执行下列步骤:在一个独立于各个用户的调用进程的操作系统变量中存储一个语言标识符;根据对一个对应于该语言标识符并且也对应于第一资源数据或第一二进制文件的第二二进制文件的检测结果:(1)根据语言标识符以及第一数据或第一二进制文件动态产生一个到第二二进制文件的路径;(2)在一个将某个标识第一二进制文件的处理模块标识符与一个标识第二二进制文件的可选模块标识符关联起来的查找表中存储该路径;和(3)使第二二进制文件中的一个可选数据而不是第一数据可被调用进程访问。
可选地,单个的模块可以包含共享资源索引。每个这样的索引均是一个指向一套或一组资源模块的指针。从一个包含这种索引的模块对资源的请求被重定向到由共享资源索引指向的索引模块组上。在模块组内,根据操作系统维护的当前语言标识符选择一个具体的模块。这允许多个模块使用相同的资源模块组并且减少了需要提供的分立资源模块的数量。更具体地说,这允许所有系统资源被指定到一个单独的资源模块中并且被系统中所有其它模块共享。这减少了资源开销并且允许操作系统更快速地加载资源。
附图说明
图1是有关一个二进制文件的示意图,该文件包含一个代码部分,该代码部分定义了一个进程,而该进程则调用相同二进制文件的一个资源部分中的一个资源。
图2是有关两个二进制文件的示意图,其中一个二进制文件包含代码并且可以包含或不包含资源,而另一个二进制文件包含资源并且可以包含或不包含代码,而第一个文件的代码定义了调用第二个文件中的资源的进程。
图3是有关被一个进程用于检索一个资源的,基于现有技术一个实施例的资源加载程序和资源搜索程序的示意图。
图4是有关一个计算机上的进程检索资源的过程的通用描述中的一个资源处理程序的示意图。
图5是有关一个调用资源数据的进程的示意图,其中该进程通过一个如图3所示的,经过对现有技术过程加以修改而得到的操作系统调用上述资源数据。
图6是示出一个基于本发明一个实施例的模块组织结构的模块图。
图7是一个示出根据本发明一个实施例而执行的步骤的流程图。
具体实施方式
参照图5,其中示出了一个调用资源数据的进程,其中该进程通过一个如图3所示的,经过对现有技术过程加以修改而得到的操作系统调用上述资源数据。修改参照图3描述的资源加载程序130和资源搜索程序135内部的进程以产生一个如图5所示的进程。在根本上,图5的进程将进程对一个具体资源的调用重定向到一个可选语言资源上以便进程接收到一个与选择的用户接口语言相关的资源而不是该进程的缺省资源。在一个实施例中,只在进程没有指定其希望加载的语言的情况下才″放弃″加载可选资源。换言之,一个进程尝试加载资源并且实际上不关心其语言。在现有技术的系统中,资源加载程序会从模块自身的资源部分或进程指定从其加载资源的一个外部模块返回资源。在有关一个多语言用户接口系统的当前实施例中,资源加载程序在进程没有为资源指定一个具体语言或其它具体分类的情况下会加载可选资源。正象图3的现有技术实施例那样,进程从资源搜索程序320请求一个存储器句柄。然而在这种情况下,如果有一个可用句柄,则该句柄是一个指向某个可选语言资源的句柄。资源搜索程序尝试识别一个由选择的用户接口语言ID 335指示的资源。
选择的用户接口语言ID 335是一项用户设置。用户在登录并且从一个选项列表中选择一个语言时335建立上述选择用户接口语言ID335。接着选择的用户接口语言ID 335被存储起来直到发生改变。
一个进程310通过向一个资源搜索程序320发送一个资源名称和类型请求一个资源的存储器句柄。如果资源位于一个没有定义调用进程310的模块中,则资源模块句柄仍然会被发送到资源搜索程序320。如果没有发送模块句柄,则由于该模块与一个产生请求资源的进程的模块相同,所以资源搜索程序已经从一个加载程序数据列表得到对模块句柄的访问。(正如在背景章节讨论的,资源搜索程序和资源加载程序经常被用来访问与产生请求进程的代码相同的二进制文件中的资源)进程也可以请求一个语言专用资源,而满足这种请求的过程可以不在涉及本发明的步骤范围内并且可以通过现有技术方法来实现(参见http://www.microsoft.com/msdn/.中有关LoadResource的描述)。在后一种情况下,一个语言ID可以被传递到资源搜索程序。
修改操作系统以便维护一个可选资源模块句柄列表323,此前已经通过调用资源搜索程序320产生了该列表。因而如果另一个进程已经从相同模块请求了一个资源并且该模块已经与一个可选资源模块关联,则可以从可选资源模块列表323中快速获得可选模块句柄。如果列表中没有针对该资源的条目,则操作系统动态产生一个可选模块路径。
为了动态产生一个可选模块路径,使用一个算法325。算法325可以基于某些假定的资源文件组织结构,该组织结构表明对于指定资源是否存在一个可选语言资源文件。在本实施例中,可选语言资源文件位于所请求的模块的路径的子目录中,其中通过一个与某个语言标识符唯一关联的文件名区分各个子目录。在各个语言的子目录内存储了可选语言资源文件,其中每个文件均在初始模块之后被加以命名。
<模块_路径\mui\<语言_ID>\<模块_名称>
换言之,操作系统从初始模块的加载路径的一个语言专用子目录加载一个可选语言资源模块。对于一个不支持多语言的系统,如果初始模块是″<路径1>\<文件名1>″,则可选语言模块的路径会是″<路径1>\mui\<语言_ID 1>\<文件名1>″,其中假定选择用户接口语言ID335所指示的语言是″语言ID 1″。
可以通过各种可选方式实现可选语言资源的组织。将它们分成分别对应于普通模块(通常在一个单语言操作系统中请求的模块)的语言专用模块可以不需要任何附加的存储器,就象对于各个资源模块,各种语言的资源被合并成一个单独的模块那样。
在指定被用来存储模块的路径结构的情况下,可以直接构造一个对应于由选择用户接口语言ID 335和初始使用的路径与模块名称指示的任何语言的可选语言模块的路径。资源搜索程序320使用这个路径提供一个资源句柄。以和现有技术相同的方式产生资源句柄。在这种情况下其差异在于资源句柄将进程引向一个资源数据350,而上述资源数据被标识在初始模块路径的一个子目录中。在图5中,资源数据350位于″二进制文件2″的一个可选资源模块内,其中选择用户接口语言ID是语言ID 2。
通过将相同名称用作调用进程提供的初始模块名称来动态产生路径和模块名称。元素<语言ID>可以是某些表示语言的紧凑代码。例如,可以是ISO 639语言标准缩写加上一个子语言代号或包含主要和辅助部分的Win32语言标识。
在本发明的一个最优实施例中,由于在假定所请求的数据有一个可选语言资源的情况下除简单地构造一个路径之外不做更多的事情,所以算法是健壮的。可以根据变化的特征度来请求可选语言。并且,可能没有可用的可选语言资源,或者有一个可用的可选资源,即在除了语言之外的某些其它方面与基本资源有所不同的资源。算法和相关过程的健壮程度足够处理和利用这些情况以及如图5所示的直接方案。
选择的用户接口语言可以是非常特定的。例如,一个用户可以请求法国,端士,或加拿大法语。算法可以使用多个步骤以便能够使一个具有某特征度的用户接口语言的系统级请求与被提供了另一个特征度的可选语言资源的可用度相一致。如果用户在登录到操作系统时请求法国法语,则只有一种与请求语言近似的可用语言。为了处理这种情况,算法和相关过程可以根据下列内置步骤层次进行操作。
首先,算法可以确定在″<模块_路径>\mui\″指定的模块路径中是否存在一个具有等价于当前用户语言ID的标识符,即具有名称″\<语言_ID>\″的子目录。如果这个第一测试失败,则算法可以确定是否存在一个″<模块_路径>\mui\″的子目录,其中该子目录具有一个和对应于当前用户语言ID的主要语言ID等价的标识符,即具有名称″\<主要_语言_ID>\″。如果没有指定系统用户语言ID,则算法可以使用一个代理解析一个子目录,例如使用某些诸如涉及日期或货币格式约定的选项,提示用户的位置的参数选择。可选地,可以调用一个中间语言可选资源模块。其它可以被分配任何期望的优先权的步骤可以从一个缺省的可选语言资源子目录中选择一个替代语言,其中用户语言ID规定的语言不可用但有一个在类似地区经常使用的预定替代语言,例如在用户语言ID中请求加拿大法语而英语可用的情况下,上述预定代替语言即是英语。上述根据一个优先权系统选择最优可选资源的过程允许增加可选语言资源的特征度。如果操作系统只配置了唯一的主要语言(例如,英语,但没有英国英语,加拿大英语等等。),则用户可以在后面增加更多的特定语言并且以透明和自动的方式实现用户的选择。
注意,上述功能不会干扰针对某特定语言的资源的正常请求,例如通过Windows中的FindResourceEx函数发出的请求。如果请求进程提供一个指定的语言ID,则上述可选语言资源方案不会把请求重定向到另一个资源模块。
在构成路径的算法325已经确定一个资源路径之后,在使其可被请求进程访问之前可以对所标识的文件进行版本检查和任何其他的完整性检查。作为参照图5描述的过程的结果,如果可选语言模块370被重新放入存储器或通过调用资源搜索程序320使其可被访问,则一个新条目可以被放入可选资源模块列表323中。最终可以向调用进程返回一个句柄以便允许进程访问请求的资源。后者可以产生一个步骤,该步骤使另一个函数,即资源加载程序330向存储器加载数据并且提供一个句柄以便进程用来访问数据。
注意,虽然图5和附带的讨论提出将模块载入存储器,但实际上可能不需要由资源搜索程序或资源加载程序完成这个操作。唯一的要求是适当的数据可被进程访问。操作系统可以通过其I/O和存储器管理程序完成实际的数据移动。前面针对图5描述的内容的重要性在于以透明的方式将一个针对不同语言有不同要求的进程对某个资源的请求自动重定向到发出请求的进程。为了使操作系统支持多语言不需要修改定义进程的代码。图5和附带的讨论描述了重定向针对资源环境中被并入也包含可执行代码的二进制文件的数据的请求的过程。可以扩充相同的基本模式以便包含对纯资源文件,例如DLL中的数据的访问。
注意,在上述讨论中,虽然一个进程需要将数据载入存储器或从存储器卸载数据,但应当从被映射到进程地址空间这种更广泛的意义上观察这种步骤。这是由于完成映射I/O的操作系统程序混淆了涉及从磁盘向存储器加载数据的具体概念。换言之,由于操作系统的I/O系统和虚拟存储器管理功能可以透明地完成这个具体步骤,在向存储器加载数据的显式步骤不必涉及的若干步骤之后,当前的操作系统可以允许一个进程访问磁盘上的数据。
上述过程可以将可选资源模块当作一个简单的数据文件映射到调用进程的地址空间上。有关这个过程的详细情况是现有技术已知的,例如在Windows中是通过定义一个被称作LoadLibrary的操作系统函数的代码来实现这种过程的。
如上所述,存在各种区别对应于不同语言的资源文件的方式。例如,与使用文件系统路径的方式不同,在某些情况下可以期望使用文件名称本身。根据本发明的一个实施例,资源文件由两个部分构成:一个初始部分和一个语言扩展部分,其中初始部分与资源模块所对应的一个可执行模块相同,而语言扩展部分指示资源模块内本地化资源的语言。
图6图解了资源模块如何与基于本实施例的对应可执行模块相关联。作为背景介绍,许多模块均是使用″C″或″C++″编程语言编写的。根据已被接受的各种实践,通常在具有一个不同于被用来表示其它可执行模块的″.c″扩展名的″.rc″扩展名,被称作″资源脚本文件″的单独源文件中定义资源。通过一个资源编译器(通常命名为″RC.EXE″)编译资源脚本文件,该编译器产生一个″.res″文件(一个具有″.res″扩展名的文件)。
资源模块通常与正常的可执行模块成对出现;可执行模块包含可执行代码,而资源模块包含可执行代码使用的资源。在链接时,资源文件被绑定到可执行文件的末端,并且资源脚本文件中定义的所有资源均变成可执行文件的一部分以便在执行期间使用。如上所述,″FindResource″和″LoadResource″函数被一个可执行模块用来从可执行模块自身或另一个已标识的可执行模块加载资源。当调用″FindResource″函数时,调用模块标识出其中定义了期望资源的可执行模块。
根据本发明的一个实施例,一个计算机系统包括多个可执行模块401,402,403,和404。为了进行讨论,这些可执行模块被命名为″myappl.dll″,″myapp2.dll″,″myapp3.dll″,和″myapp4.dll″。另外,计算机系统包括对应于多个语言的多个资源模块411,412,413,414,415,和416。每个资源模块均包含对应语言的本地化资源。注意,除了不包含可执行代码之外,这些资源模块实际上是仅仅定义了资源的正常可执行模块。还应当注意,可执行模块401-404可以包含资源定义(虽然在本发明的这个实施例中通常不会使用它们)。
资源模块411-416被加以命名以构成集合417,418,和419。一个指定集合中的所有资源模块定义了实际上相同的资源,但一个集合中的各个模块分别为其定义了具有不同语言的资源。一个指定集合中的所有资源模块被命名成两个部分。文件名的第一个部分是常规的″全部″文件名。这部分总文件名对于一个集合内部的所有模块而言均是相同的,从而表明各个模块均是一个集合的一部分。后一部分文件名是一个扩展名,该扩展名包括一个语言代码,其中语言代码的后面是一个″.mui″扩展名。这部分文件名表明所包含的资源的语言。在图6中,语言代码包括一个描述性的语言文字代号。在实际的实施例中,语言代码是一个指示某个具体语言的数字代码。
根据本发明,一个针对操作系统的资源管理器的资源请求会标识出一个诸如模块401,402,403,或404的具体模块。然而与使用该模块中定义的资源不同的是,资源管理器会识别出一个对应于在资源请求中标识的模块的资源模块集合,并且从该集合的一个资源模块提供资源。
图6图解了如何在一个可执行模块和一组资源模块之间建立对应关系。可以通过两种方式建立对应关系。第一种对应关系如模块401,402和对应的资源模块集合417,418所示。当使用这类对应时,每个可执行模块均具有一个对应的唯一资源模块集合。在这种情况下,命名为″myapp1.dll″的可执行模块401具有一个对应的资源模块集合417,该集合依次包含分别被命名为″myapp1.dll.french.mui″和″myapp1.dll.english.mui″的资源模块411和412。注意,资源模块文件名的第一个第一与对应可执行模块的文件名相同。这样就将资源模块411和412标识成属于一个对应于可执行模块401的集合。
类似地,命名为″myapp2.dll″的可执行模块402具有一个对应的资源模块集合418,该集合依次包含分别被命名为″mya即2.dll.french.mui″和″myapp2.dll.english.mui″的资源模块413和414。
当一个应用程序或可执行模块从资源管理器请求一个资源并且标识出一个将从其获得资源,诸如模块401的具体可执行模块时,操作系统资源处理程序首先识别一个与所标识的可执行模块相关的资源模块集合。通过记录所标识的诸如″myapp1.dll″的可执行模块的文件名可以实现这个操作。其文件名从这个字符串开始的任何资源模块均属于与所标识的可执行模块相关的资源模块集合。在这种情况下,资源模块411和412具有从″myapp1.dll″开始的文件名,因而属于对应于所标识的模块401的期望资源模块集合。
接着,资源处理程序根据一个以独立于针对资源处理程序的请求的方式获得的语言标识符选择资源模块集合中的一个资源模块。上述操作的实现方式是构造一个从所标识的模块的文件名(″myapp1.dll″)开始的资源模块文件名,并且接着继续通过对应于当前语言标识符的语言代码构成一个后跟″.mui″的扩展名。这样,如果当前语言标识符和对应语言代码是″法语″,则资源处理程序构造一个文件名″myapp1.dll.french.mui″.资源管理器接着从这个文件中检索出所请求的资源并且将其提供给发出请求的应用程序或可执行模块。
可执行模块和资源模块之间的第二种对应关系如可执行模块403,404和资源模块集合419所示。根据本发明,某些可执行模块可以包含共享资源索引。每个共享资源索引均标识一个对应于不同语言的资源模块集合。在所述的实施例中,共享资源索引指示一个文件名或文件标识符的一部分。在图6所示的例子中,可执行模块403和404均包含一个共享资源索引420。适当的资源模块集合由一个字符串标识,该字符串规定了一个资源文件的文件名的第一部分,例如本例子中的″shared.dll″.在这种情况下,不同可执行模块403和404包含相同的共享资源索引:″shared.dll″.因而这两个可执行模块均指向一个单独的共享资源模块集合419。
当一个应用程序或可执行模块从资源管理器请求一个资源并且标识出一个将从其获得资源,诸如可执行模块403或404的模块时,资源处理程序通过识别一个资源模块集合来作为响应。通过根据共享资源索引和操作系统维护的当前语言标识符选择或构造一个文件名可以实现这种操作。具体地,通过在共享资源索引(在这种情况下为″shared.dll″)后面附加扩展名″.language.mui″来构造一个文件名,其中″language″是一个对应于当前语言标识符的语言代码。资源处理程序接着从具有所构造的文件名的资源文件提供所请求的资源。
这个方案允许将资源模块统一到一个具有多个可执行模块的工程项目中。与使每个单独的可执行模块具有一个不同的英语语言资源模块的方式不同的是,一个单独的英语语言资源模块可以支持多个可执行模块。这样就大大减少了一个复杂应用中需要的单独资源模块的数量。
图7图解了在本发明的这个实施例中执行的步骤。步骤430包括接收一个资源请求。通常由一个应用或可执行模块通过上述″FindResource″和″LoadResource″函数向资源处理程序发出这种请求。作为请求的一部分,应用指定所请求资源的名称或ID并且还提供一个指示将从其获得资源的模块的模块标识符。模块标识符是一个对应于期望模块的操作系统句柄。期望模块具有一个为操作系统已知的文件名。
步骤431包括确定模块标识符所标识的模块是否包含一个共享资源索引。在所述的实施例中,共享资源被实现成一个具有预定或保留名称的资源。所述的实施例使用资源名称″RT MUI″。这个资源的值被设置成一个规定某个资源模块文件名的第一部分的字符串或宽字节字符集字符串。例如,如图6所示,″RT MUI″资源可以被设置成″shared.dll″。
如果步骤431发现在资源请求所标识的模块内存在″RT MUI″资源,则执行步骤432以便从一个由″RE MUI″资源值标识的资源模块集合中选择一个具有适当语言的资源模块。在所述的实施例中,″RT MUI″数值包括一个文件名的第一部分,因而标识出一组均从相同数值开始的文件名。通过在″RT MUI″共享资源索引后面附加一个扩展名来选择具有适当语言的模块。扩展名由字符串″.language.mui″构成,其中″language″是一个对应于由操作系统的语言标识符指示的语言的语言代码。
如果步骤431在资源请求所标识的模块内没有发现一个共享资源指示符,则执行步骤433以便从一个由所标识模块的文件名指示的资源模块集合中选择一个具有适当语言的资源模块。所标识的模块的文件名被用作一个资源模块文件名的第一部分,因而标识出一组均从相同字符串开始的文件名。通过在所标识的模块的文件名后面附加一个由字符串″.language.mui″构成的扩展名来选择一个具体的模块,其中″language″是一个对应于由操作系统的语言标识符指示的语言的语言代码.
步骤434在步骤432或433之后,并且包括从构造的文件名标识的资源模块提供所请求的本地化资源。
通过这种方式,在不需要发出请求的模块采取任何选择具体语言的明显动作的情况下可以提供具有适当语言的资源。
在某些情况下,当前语言标识符指示的语言不能被一个具体资源模块集合的资源模块表示。这了解决这个问题,资源处理程序提供一个回退机制,该机制试图提供尽可能最优的语言选择,即使在语言标识符指示的实际语言不可用时也是如此。具体地,如果没有符合语言标识符的资源模块,则资源处理程序按照优先权的降序根据下列语言选择一个可选的资源模块:
语言标识符指示的语言的母语;
系统的缺省语言;
系统缺省语言的母语;
美国英语;
正统英语。
术语″正统″是指某个包含多个子集的通用语言。例如,一个系统可以使用″加拿大法语″。加拿大法语的正统语言是法语。当最初配置一个计算机时设置一个″系统缺省″语言,并且根据操作系统语言标识符当前指示的语言,″系统缺省″可以发生改变。
虽然前面已经通过特定于语言的结构功能和/或方法步骤描述了本发明,但应当理解所附权利要求书定义的本发明不必受上述特定功能或步骤的限制。而是将特定的功能和步骤公开成实现权利要求书提到的发明的最优形式。