📄 csdn_文档中心_microsoft windows 2000 应用程序兼容性.htm
字号:
NULL);
}
else
SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
ZeroMemory(&pfd,sizeof(PROTECTED_FILE_DATA));
iCount = 0;
while ( g_pfnSfcGetNextProtectedFile(NULL, &pfd) != 0 )
{
// 为此“ANSI 应用程序”将 WCHAR 转换到 ANSI
iLen = WideCharToMultiByte(CP_ACP,NULL,pfd.FileName, wcslen(pfd.FileName),
szFileName,260,NULL,NULL);
szFileName[iLen] = '\0';
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)szFileName);
iCount++;
}
}
</CODE></PRE>
<P>另一个更为直接的 API 是 <B>SfcIsFileProtected</B>。该 API
能更为便捷地为绝大多数应用程序直接调用,并回答以下问题:“看看这一文件,它是否受到保护?”但是请记住,它需要指向这一文件的完整路径。您不能只是简单地指定
NTS.sys,而是需要给出到达 NTS.sys 所处位置的路径。如果您将这一文件名传递给
API,它会说:“是的,这个文件已受到保护”,或“这不是一个受保护的文件”。在您进行任何备份或恢复操作时都需要使用该
API。如果您希望进行任何安装设置,或可能会更新某一系统文件,您都可以调用这一
API。如果您希望将某一目标文件置于系统目录中,在进行这一操作之前,您需要调用这一 API,以避免取消 Windows
文件保护功能。下一版的 Windows Installer(与 Windows 2000
一同发布)将在复制文件之前进行检查,因此不会意外地启动 WFP。 </P><PRE><CODE>BOOL WINAPI SfcIsFileProtected (IN HANDLE RpcHandle,IN LPCWSTR ProtFileName);
//
// 此函数使用“文件”打开对话框,以便从用户获取文件名并检查其是否受保护。
void CheckFileForProtection(HWND hWnd)
{
OPENFILENAME OpenFileName;
CHAR szFile[MAX_PATH] = "\0";
CHAR szSystem32[MAX_PATH];
strcpy( szFile, "");
ZeroMemory(&OpenFileName, sizeof(OPENFILENAME));
// 填充 OPENFILENAME 结构以支持模板和挂接。
OpenFileName.lStructSize = sizeof(OPENFILENAME);
OpenFileName.hwndOwner = hWnd;
OpenFileName.hInstance = hInst;
OpenFileName.lpstrFile = szFile;
OpenFileName.nMaxFile = sizeof(szFile);
OpenFileName.lpstrTitle = "Select a File";
OpenFileName.Flags = OFN_FILEMUSTEXIST;
if (g_pfnSHGetFolderPath != NULL )
g_pfnSHGetFolderPath(NULL, CSIDL_SYSTEM, NULL, NULL, szSystem32);
else
szSystem32[0] = '\0';
OpenFileName.lpstrInitialDir = szSystem32;
// 调用公共对话函数。
if (GetOpenFileName(&OpenFileName))
{
// 检查文件
WCHAR wzFileName[260];
int iLen;
iLen = MultiByteToWideChar(CP_ACP,NULL,szFile, strlen(szFile), wzFileName, 260);
wzFileName[iLen] = '\0';
if (g_pfnSfcIsFileProtected(NULL, wzFileName) == TRUE )
{
MessageBox(hWnd,"Is Protected", szFile, MB_OK);
}
else
MessageBox(hWnd,"Is NOT Protected", szFile, MB_OK);
}
</CODE></PRE>
<H3>组件检查</H3>
<P>我们发现导致无法在 Windows 2000
上安装应用程序的另一个原因是组件检查功能。显然,我们操作系统的每一版本都是由多个不同的组件组成。这些组件包括
TAPI、MAPI、Microsoft DirectX(R)
等等。我们发现应用程序会对什么组件处于什么位置,以及是否存在某一组件作出自己的假设。应用程序会因为甲组件存在而假定乙组件也存在,因为某一组件的版本
2 存在而认定另一组件的版本 3
也必然存在。如果您需要用到某一组件,则一定要检查系统中是否存在这一组件,以及它是否位于正确的级别。</P>
<P>除此之外,开发人员还会假设 Windows NT 中没有
DirectX。有时候某一语句为真,而且应用程序在编制时也认为它可能为真。然后在对其进行检查时,因假设 Windows
2000 没有 DirectX,它就会声明:“噢,我无法运行。”但是 Windows 2000 带有
DirectX,这一假设是不正确的。</P>
<P>我们遇到的另一问题是硬编码问题,应用程序如果假定组件所处的位置是错误的,则根本无法对路径进行硬编码。</P>
<P>另一个例子是,Windows 2000 现在包含 TAPI(最新版本为 TAPI 3.0)和
DirectX(最新版本为 7),而不是默认情况下的 MAPI。过去总是认为如果操作系统是 Windows
NT,其中应该包含
MAPI。但现在的情况不同了。如果您使用某一组件,则一定要检查这一组件是否存在,而不能根据平台或组件等作出任何假设。</P>
<H3>在错误的位置安装文件</H3>
<P>我们在安装方面所发现的另一问题是人们放置文件的位置出错。如果您对别人置于某处的某些文件进行升级,那没关系;只要将它们置于用户所希望的位置即可。但有些文件在第一次安装时,需要将其置于“Program
Files”目录下。</P>
<P class=indent><B><B>注意 </B></B>不一定是
C:\Program Files。有时候是这一目录,有时候则不是。比如在我的机器上就不是。我一般都将 C 分区留给
Windows 98,而将 Windows NT 分区安装到其他分区。 </P>
<P>我们希望您尽可能不要将文件置于 Windows 目录,或 System32
等任一子目录。虽然这样做本身没有什么坏处,过去我们也常常希望您如此,因此我们无法完全禁止这一做法,但我们现在希望系统中的所有文件更加有组织一些。我们已经发现,用户对
System32
目录下成百上千的文件深感头痛,对这些文件一无所知,因此也无法删除他们。您每每听到人们这样说:“每年,您都要清理系统,并从头开始重装
Windows”。卸载和清理程序已成为软件市场上最流行的应用程序。我们希望系统保持有序状态,并使操作过程更加简化。</P>
<P>可能的话,我们甚至希望您将某些共享组件也写到别处;Microsoft Visual Basic(R)
在这方面就是一个比较好的例子。许多应用程序都会用到这一组件。旧版 Visual Basic
总是安装在系统目录中,而现在我们将它置于 Program Files 的一个指定文件夹内。 </P>
<P>如果要查找文件应该放置的位置,可以调用一个名为 <B>SHGetFolderPath</B>
。<B>SHGetFolderPath</B> 是 Windows 2000 的一个组成部分。它在第二版的 Windows
98 中也已经存在。如果您发现系统中没有这一 API,您可以对S HFolder.dll 进行分发。该 DLL
将解开这一名为 <B>SHGetFolderPath</B> 的新 API 的外壳。这一 API
了解每一特殊文件夹在系统中所处的位置。您可以在 SDK 中找到该
API。它是一个非常长的清单,其中列出了您能够考虑选用的每一个文件夹。</P>
<P>需要注意,旧版的平台只支持以下四个
CSLID。如果您要查找某一特定目录,发现该目录不存在,<B>SHGetFolderPath</B>
能够为您创建该目录,条件是您已指定了这一操作,但在 Windows 95 等后向平台中,这一过程只能对以下四个 CSIDL
有效:</P>
<P class=indent>CSIDL_PERSONAL</P>
<P class=indent>CSIDL_APPLICATIONDATA</P>
<P class=indent>CSIDL_MYPICTURES</P>
<P class=indent>CSIDL_LOCAL_APPLICATIONDATA</P>
<P>以下代码示例显示了 <B>SHGetFolderPath</B> 的应用方式;它是一个非常简单易用的
API。有一点需要注意:如果希望代码在所有平台上都能运行(包括 Windows 2000 等自带
<B>SHGetFolderPath</B> 的平台和 Windows 95 等不带 SHGetFolderPath
的平台),应用程序必须与 SHFolder.dll 中的实施过程进行动态链接。</P><PRE><CODE>
// SHGetFolderPath can work everywhere SHFOLDER is installed.
HMODULE hModSHFolder = LoadLibrary("shfolder.dll");
if ( hModSHFolder != NULL )
{
(*(FARPROC*)&g_pfnSHGetFolderPath =
GetProcAddress(hModSHFolder,"SHGetFolderPathA"));
}
else
g_pfnSHGetFolderPath = NULL;
}
if (g_pfnSHGetFolderPath != NULL )
g_pfnSHGetFolderPath(NULL, CSIDL_SYSTEM, NULL, NULL, szSystem32);
else
szSystem32[0] = '\0';
OpenFileName.lpstrInitialDir = szSystem32;
</CODE></PRE>
<H3>安全性问题</H3>
<P>最后,作为设置和安装的最后一个问题,我们将讨论随 Windows 2000 出现的几个安全性问题:
<UL type=disc>
<LI>高级用户应能安装整个系统范围的应用程序。我们发现有些应用程序坚持只能由管理员进行这类安装。对于锁定的机器,企业仍然希望许多不同用户,或一天中有两三个用户能够进行共享;或者是在特定的某一天,所有雇员都能够使用这一系统。他们只是不希望任何人都能以管理员权限对系统任意更改,为所欲为。许多客户要求高级用户(不仅是管理员)也能够完成应用程序的安装。<BR><BR>
<LI>另一条,所有人都可以安装供自己(而不是系统中的任何人)使用的应用程序。如果我希望玩某个游戏,我就应该能安装该游戏,而且不让系统中的其他任何人使用这一游戏。但请记住,非高级用户不能向
“Program Files” 目录写东西;该用户无法对 HKEY_LOCAL_MACHINE
进行写操作。在安装过程中,您应能打开
HKEY_LOCAL_MACHINE,查看您对它有没有写权限,然后让它作出如下声明:“您不能对该处进行写操作;是否希望这一应用程序只供个人使用?”
<BR><BR>
<LI>另一个安全性问题是默认的服务器权限。如果您试图安装服务器应用程序或服务,而使用的是非特权服务帐户(意即,您没有使用本地系统的帐户,也没有使用作为本地管理员组的成员所建立的帐户),则该帐户基本上不可能拥有实际运行服务所需的特权。在
Windows 2000 中,非特权用户(实际上是非特权服务帐户)所拥有的权限与 Windows NT 4.0
中不同。前者拥有的权限较少。例如,非特权用户无法在 Windows
系统目录的任何地方写入东西。如果您拥有一个正在运行的服务器,该服务器试图进行某些操作,或试图安装某些东西,但它可能没有具备适当的权限。如果您正在运行服务器应用程序,请确认它已登录了正确的帐户,并拥有正常运行所需的所有权限。</LI></UL>
<H2><A name=win2000appcomp_topic3></A>Windows 2000 兼容性问题</H2>
<P>我要讨论的下一个问题被我称之为 Windows 2000 兼容性问题,这里指的是我们对 Windows
平台进行的某些更改,其目的是推动平台不断进步,并实现我们为用户提供更为可靠的平台的目标。这些改动将影响某些应用程序在
Windows 2000 上运行的方式。 </P>
<H3>设置前台窗口</H3>
<P>我们以一个相当简单的操作开始:设置前台窗口。实际上,这一变动始于 Windows
98。不能指望只是简单地由应用程序调用 <B>SetForegroundWindow</B>
,然后您的窗口就能自动地变更为前台窗口。所有这些都是为了防止在任何人希望跳到最前台时出现令人烦恼的选项。您正在兴致勃勃地键入,突然弹出了一个窗口,要请求某种操作。您可能在键入过程中毫无意识地对某些根本不了解的东西作出了肯定的答复。</P>
<P>为了防止出现这种情况,对应用程序何时能成为前台应用程序制订了规则。其实在 Windows 98 中这些规则已经存在:
<UL type=disc>
<LI>如果您的进程已经是前台进程,则可以取前台窗口。 <BR><BR>
<LI>如果您的进程刚刚由前台进程启动,则可以取前台窗口。 <BR><BR>
<LI>如果您的进程收到最后一次输入,则会变为前台窗口。<BR><BR>
<LI>如果此时没有前台窗口,则可以取前台窗口。<BR><BR>
<LI>如果正在对前台进程进行调试,则每个人都可以取前台窗口。<BR><BR>
<LI>如果发生了前台超时锁定(某一段时间内前台锁定没有任何操作,而且不会作出响应),那么别人可以取得前台窗口。<BR><BR>
<LI>如果当前任何系统菜单是活动的,则您的应用程序将无法取得前台。这主要是为了防止出现以下令人烦恼的情况:您正在使用“开始”菜单,并沿着它的分支菜单正要启动某个应用程序,突然这些菜单全部消失。
Windows 2000 中新增的这一规则可以防止出现这种情况。</LI></UL>
<H3>超级隐藏文件</H3>
<P>Windows 2000 中增加的另一个新特性称为“超级隐藏文件”(Super Hidden
Files)。这里,系统会将几个文件同时标记“系统”和“隐藏”属性。文件仍位于原位置,我们还可以应用这些文件;只是当您进入
Windows
资源管理器之后,这些文件不会显示出来。即使选中“显示隐藏文件”,也无法看到它们。在文件夹的属性列表中有一个新的复选框,该复选框将允许用户看见这些文件,但普通用户不会选中该选项,所以无法看到这些文件。</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -