首页 目录页 热情软件屋 问专家

李海文选

为Windows添加多配置能力

李海

柳扬

本文发表在国际电子报1996年第23期

  MS-DOS 6.x提供了一个极为实用的功能:多配置启动。利用这一功能,用户可以轻松地管理启动文件CONFIG.SYS中的设置。可惜,Windows 3.x并没有提供这一功能,但实际工作中用到多配置功能的地方还是不少的:

  针对以上问题,我们设计了一个方案作为Windows多配置启动的一种尝试,现在介绍给大家,希望对大家的工作有所帮助。

  众所周知,Windows将各种系统设置存放在WIN.INI和SYSTEM.INI中,并将有关程序组的信息存放在PROGMAN.INI中,这三个文件的地位与DOS的AUTOEXEC.BAT和CONFIG.SYS相当。所以 ,要想为Windows添加多配置启动功能的关键是在Windows启动前对三个启动文件进行正确的修改,这样Windows就能按照我们的要求进行启动,而多配置的实质正是将手工的修改以特定的方式储存起来,以供需要的时候加以调用,储存方式可以采用批处理、宏语言等等。

  我们采用将批处理和从命令行直接修改配置文件相结合的方案,这个方案的优点是方法简单易于实现、速度快,且与DOS和Windows的版本无关。整个方案可以分为三步:显示菜单、根据用户选择修改配置文件和启动Windows。这里,我们采用批处理的方法来实现,用户也可以根据自己的爱好使用高级语言来完成。

  在各种报刊上已有很多关于用批处理的方法来显示菜单的介绍,我们不打算赘述。这里的示例采用的方法是DOS 6.x的CHOICE命令。

  我们重点要讨论的问题是如何从命令行修改配置文件。在DOS中并没有从命令行直接修改配置文件的命令,所以我们专门设计了一个小程序来解决这个问题,源程序附在文后。该程序是用Turbo Pascal写成的,我们使用Turbo Pascal 6.0和7.0进行编译,均获得了通过。其命令行格式为
INILE Filename[.INI] Section Key Value

  其中,Filename为欲修改的设置文件的文件名,默认扩展名为INI。Windows的配置文件由若干个段(Section)组成,每个段中可能有几个设置行,每行的格式均为:关键字=值。INILE命令行中的Section、Key和Value就分别对应着配置文件中的段名、关键字和值。如果段名中 含有空格,可以用"["和"]"将段名括起来,如[Microsoft Word 5.0]。如果关键字包括空格, 则可以用引号将关键字括起来,如"Epson LQ1600K"。按照Windows的规定,段名、关键字都是忽略大小写的,INILE也依此处理。有了INILE,就可以用我们的方案来进行Windows的多配置了,当然效果如何,还要取决于您对Windows的了解和想象力。如果您对Windows的设置文件了解得不多,可以阅读一下Windows目录中的WIN.WRI和SYSTEM.WRI文件。另外,Microsoft Windows Resource Kit(中文名称:《Windows资源大全》)和Norton Utilities 8.0中也有大量的相关介绍。

  下面我们从最初提到的三个方面入手给出示例。

  (1)设置桌面

  Windows的一些桌面设置,象壁纸(Wallpaper),都保存在WIN.INI的Desktop段中,所以修改该段就可以实现桌面设置了。

  下面的这段批处理程序是用来演示如何更改壁纸设置的。

  @echo off
  cls
  echo.
  echo A Leaves
  echo B Arches
  echo C 256 Colors
  echo.
  choice/c:abc Choose wallpaper
  if errorlevel 3 inile win.ini desktop Wallpaper 256color.bmp
  if errorlevel 2 inile win.ini desktop Wallpaper arches.bmp
  if errorlevel 1 inile win.ini desktop Wallpaper leaves.bmp
  win

  请注意:这里if errorlevel语句必须按降序排列,这是DOS的要求。

  (2)设置多种显示模式

  在Windows中要改变显示模式,一般是通过Windows的SETUP程序来完成,比较麻烦。如果每次启动前可以通过菜单选择显示模式就好了。其实,SETUP程序所做的工作也不过是根据选定的显示模式寻找相应的驱动程序(如果没找到,就从安装盘上释放驱动程序到当前系统),并 修改SYSTEM.INI和PROGMAN.INI中的有关设定,这样在Windows再次启动时,新的显示模式就可以生效了。

  最简单的改变显示模式的方法,只需要将SYSTEM.INI中的boot段中的display.drv一行改写即可。例如,VGA模式下该设置为display.drv=VGA.DRV,而Trident 800*600*256色(512K VRAM)模式下为display.drv=T800-5.DRV,所以若需将显示模式从VGA模式改为Trident 800* 600*256色(512K VRAM)模式,就将SYSTEM.INI中的boot段中的display.drv行改写为display.drv=T800-5.DRV就可以了。这样做的前提条件,是在当前Windows系统的SYSTEM子目录下必须有T800-5.DRV这个文件。如果您已经使用过这个模式,那么这个文件应当是存在的,如果从来没有使用过,可以先通过SETUP程序设置这个模式,SETUP程序会自动将这一驱动程序拷贝到硬盘上,当然您也可以使用EXPAND命令手工地从安装盘上将其释放出来。

  下面的例子展示了如何使用这种方法在启动前设置Windows的显示模式:

  @echo off
  cls
  echo.
  echo A VGA
  echo B Trident 800*600-256c
  echo C Trident 1024*768-16c
  echo.
  choice/c:abc Choose mode
  if errorlevel 3 inile system.ini boot display.drv w1024f.drv
  if errorlevel 2 inile system.ini boot display.drv T800-5.drv
  if errorlevel 1 inile system.ini boot display.drv vga.drv
  win

  实际上,SETUP为改变显示模式所进行的修改比上面所说的要复杂一些,还是以显示模式从VGA模式改为Trident 800*600*256色(512K VRAM)模式为例,SETUP要将SYSTEM.INI文件由

  [boot]
  386grabber=vga.3gr
  display.drv=vga.drv
  [boot.description]
  display.drv=VGA
  [386Enh]
  display=*vddvga

  修改为

  [boot]
  386grabber=V7VGA.3GR
  display.drv=T800-5.drv
  [boot.description]
  display.drv=TRIDENT 800*600-256c for 512K Board
  [386Enh]
  display=VDDTVGA.386

  同时,SETUP将PROGMAN.INI文件中的Settings段的display.drv=vga.drv修改为display.drv=T800-5.DRV。如果您担心只简单地修改SYSTEM.INI文件不够保险,也可以完全照此修改。

  (3)自动调用Windows应用

  在Windows的配置文件中,有三处可以实现类似AUTOEXEC.BAT的自动调用Windows应用的功能。一处是WIN.INI中WINDOWS段中的"LOAD"行,一处是WIN.INI中WINDOWS段中的"RUN"行,另一处是PROGMAN.INI中SETTINGS段中的"STARTUP"行。我们采用的是第三个办法。这种办法是指定一个程序管理器的程序组代替STARTUP.GRP组(中文版为CSTARTUP.GRP)作为启动程序组,它的优点是您可以在Windows的程序管理器中来改变各程序组的内容,而不必修改启动批处理程序,而且这种方法比较适合一次启动多个应用程序。具体的过程请看下面的这段批处理程序。

  @echo off
  cls
  echo.
  echo A Microsoft Excel 5.0
  echo B Visio 3.0
  echo C Photo Styler 2.0
  echo.
  choice/c:abc Choose Application
  if errorlevel 3 inile progman.ini Settings Startup PS2
  if errorlevel 2 inile progman.ini Settings Startup VISIO
  if errorlevel 1 inile progman.ini Settings Startup EXCEL
  win :

  在运行这段程序前,您应先建立PS2.GRP、VISIO.GRP和EXCEL.GRP,并在每个程序组内放置希望运行的程序的图标。最后一行中的冒号是为了在Windows启动时忽略启动画面。

  现在,您就可以动手来配置您的Windows了。

附录:INILE源程序
  program INILE;
  var
    inaline:byte;
  filename,section,key,value,line:string;
  f:text;
  procedure help;{显示帮助信息}
  begin
     writeln('Syntax:#13#10,'INI filename[.ini][section] key value'#13#10,
      'Example:'#13#10' INI win.ini[BCW4.0 Installation]');
     halt
  end;
  procedure getinfo;{命令行分析}
  var i,j:byte;
  begin
     filename:=paramstr(1);
     if pos('.',filename)=0 then filename:=filename+'.ini';
     {$I-}assign(f,filename);reset(f);{$I+}
     if(IOResult<>0)then
          begin writeln(filename,' not found!');halt end;
     if inaline=1 then exit;
     section:=paramstr(2);
     i:=3;
     if copy(section,1,1)<>'['then section:='['+section+']'
     else
          while(copy(section,length(section),1)<>']')and(i<=inaline) do
           begin section:=section+' '+paramstr(i);i:=i+1 end;
     if i>inaline then exit;
     key:=paramstr(i);i:i+1;
     if copy(key,1,1)=''then
         begin
          key:=copy(key,2,length(key)-1);
          while(copy(key,length(key),1)<>'')and(i<=inaline) do
             begin key:=key+''+paramstr(i);i:=i+1 end;
          key:=copy(key,1,length(key)-1)
       end;
     if i>inaline then exit;
     for j:=i to inaline do value:=value+paramstr(j)+''
  end;
  function UCaseTrim(s:string):string;{将字符串转为大写,并去掉首尾空格}
  var i:byte;
  begin
     for i:=1 to Length(s)do s[i]:=UpCase(s[i]);
     for i:=1 to Length(s)do
          if(s[i]<>'')and(s[i]<>chr(9))then break;
     s:=copy(s,i,Length(s)-i);
     for i:=Length(s)downto 1 do
        if(s[i]<>'')and(s[i]<>chr(9))then break;
        UCaseTrim:=copy(s,1,i);
  end;
  procedure forvalue;{修改配置文件}
  var g:text;i:longint;
  procedure overwrite(action:boolean);
  var j:longint;
  begin
     close(f);reset(f);
     {建立临时文件}
     assign(g,copy(filename,1,pos('.',filename))+'$$$');rewrite(g);
     for j:=1 to i-1 do
          begin readln(f,line);writeln(g,line) end;
     writeln(g,key,'=',value);if action then readln(f);
     while not eof(f) do
          begin readln(f,line),writeln(g,line)end;
     close(g);close(f);
     erase(f);rename(g,filename);
  end;
  begin
     i:=0;
     while not eof(f)do
          begin
           readln(f,line);i:=i+1;
           if UCaseTrim(line)=UCaseTrim(section) then
                begin{找到了指定段}
              repeat
                   readln(f,line);i:=i+1;
                 if UCaseTrim(copy(line,1,pos('=',line)-1))=UCaseTrim(key)then
                    begin overwrite(true);exit end;{找到指定关键字}
              until eof(f)or (copy(line,1,1)='[');
              overwrite(false);exit{未找到指定关键字,加入}
               end
         end;
     writeln('Section not found!');
   end;

  begin
     inaline:=paramcount;
     writeln('PowerDOS--INI Modifier 1.0 Limited Edition'#13#10,
         'Copyright(c)1995,Zeal SoftStudio.',#13#10'Authur:Yang Liu, Hai Li'#13#10);
      if inaline=0 then help;
     section:='';key:='';value:='';
     getinfo;
     if value=''then help;
     forvalue;
   end.

回到《李海文选》目录

如果您有任何建议,请给我发电子邮件:
版权所有 李海,热情软件屋 1997-2006


WU Banner from WebUnion Chinese Network