在Windows和Delphi中实现应用程序可移植性?

时间:2011-07-16 22:09:08

标签: windows delphi delphi-7 portability

我们有这个应用程序不会写入Windows注册表或将其配置文件(例如INI文件)存储在用户的配置文件中;相反,它将其配置文件存储在程序的目录中。维基百科有此声明

  

便携式应用程序(便携式应用程序)是一种计算机软件程序,旨在独立于操作系统运行。此类应用程序存储在可移动存储设备上,例如CD,USB闪存驱动器,闪存卡 - 仅在存储介质上存储其程序文件,配置信息和数据。

所以我们的问题是,这是否使我们的应用程序成为真正的便携式应用程序(便携式应用程序)

我应该指出,如果应用程序在写保护介质上,我们使用下面的函数,因此它不会尝试写入该介质。

function GetTempFile(): string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
  Windows.ZeroMemory(@Buffer, System.SizeOf(Buffer));
  SysUtils.StrPCopy(Buffer, SysUtils.ExcludeTrailingBackslash(SysUtils.ExtractFilePath(System.ParamStr(0))));
  Windows.GetTempFileName(Buffer, '~', 0, Buffer);
  Result := string(Buffer);
end;

function IsMediumWriteProtected(): Boolean;
var
  ErrorMode: Word;
  hHandle: THandle;
begin
  ErrorMode := Windows.SetErrorMode(SEM_FAILCRITICALERRORS);
  try
    hHandle := Windows.CreateFile(PChar(GetTempFile()), GENERIC_WRITE, 0, nil, 
      CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);
    try
      Result := (hHandle = INVALID_HANDLE_VALUE);
    finally
      Windows.CloseHandle(hHandle);
    end;
  finally
    Windows.SetErrorMode(ErrorMode);
  end;
end;

2 个答案:

答案 0 :(得分:11)

真正的便携式应用程序,如果这确实是您的问题,应该:

  • 无需任何安装。
  • 在将其复制到的任何地方工作。

我自己的便携式应用程序的格式塔定义并不总是要求当应用程序位于只读位置时应用程序正常工作,除了这个维基百科参考之外,我不确定它是什么在野外的标准。你正试图遵循维基百科文章中所阐述的法律条款,这真是太棒了。让我感到烦恼的是,你从维基百科文章中提到的引用包含了一些内部矛盾;如果定义都期望必须支持CDROM(或者您的应用程序不可移植),并且还指定数据应该仅存储在该介质上。你遇到了这个矛盾,现在正在违反法律条文的一部分,以避免违反其中的第一部分。所以这个定义要么阻止你在这种情况下保存任何东西,要么这个定义实际上不是法律本身,你可以自由地按照你的意愿去做,前提是我遵循上面提到的两点。

便携式应用程序的极简主义定义是我上面提到的,除了这两点之外你应该做的,应该是适合你的用户的。

我真的没有看到SO上的任何人如何能够为您提供便携性方面的绿灯。您只能通过测试来真正验证可移植性,并且最好通过一组人进行测试,例如beta测试或fieldtest用户。我也没有看到StackOverflow是测试二进制文件的帮助请求的好地方。这是一个询问编程问题的网站,不是用于形成beta测试,现场测试等,也不是用于推广您的应用。事实上,我没有看到我们如何安全地从您下载二进制文件,并没有冒险运行我们的系统运行我们从链接下载的二进制代码。我建议你删除二进制文件的链接。

我会做的测试:

  • 将它放在USB密钥上,并在几个不同的干净窗口系统上的几台不同的PC上运行,包括XP,Vista,Win 7,Windows Server 2008,多个服务包级别(无SP,Sp1,Sp2) ,XP等上的Sp3),以及几个不同的脏系统(安装了Visual Studio,安装了delphi,安装了办公室和各种防病毒系统的系统)。

  • 确保不需要外部运行时BPL / DLL或其他运行时内容,除了那些与可执行文件位于同一文件夹中的内容(并排配置)。这样就不必为用户的路径修改用户的路径,也不必担心DLL地狱的混乱。

  • 检查应用程序中是否存在注册表写入或应用程序文件夹外的文件系统写入。 SysInternals Process Monitor非常适用于此。

答案 1 :(得分:6)

不要使用Windows.GetCurrentDirectory()来检索可执行文件的目录。它返回进程的当前工作目录,该目录可以在进程的生命周期内动态更改,因此无法保证每次都能获得正确的目录。要可靠地获取应用程序目录,请改用Sysutils.ExtractFilePath(Sysutils.ParamStr(0))。在内部,它使用Windows.GetModuleFileName(nil)来获取应用程序的完整路径,然后截断可执行文件名,留下所需的目录路径。