【问题标题】:Inno Setup: Generated folder name works in Windows XP but not Windows 7Inno Setup:生成的文件夹名称适用于 Windows XP 但不适用于 Windows 7
【发布时间】:2015-02-18 04:49:29
【问题描述】:

在 [Files] 部分,我使用 Pascal 脚本,它调用我自己的 DLL 来生成我希望安装程序文档的文件夹名称。我的 DLL 和我的 Pascal 脚本似乎工作正常,但是当我在 Windows 7 上运行我的安装程序时,Inno Setup 使用目录名作为文件名,而不是将文件名附加到目录名,我最终得到了所有 3文档文件复制到具有我希望目录具有的名称的文件中。奇怪的是,当我在 Windows XP 上运行该代码时,它确实可以正常工作。

以下是一些相关代码:

[文件]部分:

[Files]
Source: "doc 1.pdf"; DestDir: "{code:DocumentFolder}";
Source: "doc 2.pdf"; DestDir: "{code:DocumentFolder}";
Source: "doc 3.pdf"; DestDir: "{code:DocumentFolder}";

帕斯卡脚本:

// Get the path to the documentation folder
// DocPath() returns a path name without a trailing backslash
// unless it returns a null string.
function DocumentFolder(Param: String) : String;
var
  s : String;
  k : integer;
begin
  SetLength(s, 255);
  k := DocPath(s); // Path to "MyCompany\MyProg" folder or something like it
  if 0 = k then s := ExpandConstant('{app}'); // Just use the program folder if there is no public folder
  Result := s; 
end;

我编写脚本的原因是我希望将文档放入系统公用文件夹中的文件夹(如果有),但也可以放入没有公用文件夹的系统上的程序文件夹中。

如果我错过了一些完全简单的方法,请告诉我。

无论如何,当我在 Windows 7 系统上运行它时,根据 Inno Setup 的调试日志,这是我得到的:

[10:47:42.406]   Dest filename: C:\Users\Public\MyCompany\MyProgDocs
[10:47:42.409]   Time stamp of our file: 2002-07-10 10:33:02.000
[10:47:42.412]   Installing the file.
[10:47:42.453]   Successfully installed the file.
[10:47:42.458]   -- File entry --
[10:47:44.595]   Dest filename: C:\Users\Public\MyCompany\MyProgDocs
[10:47:44.598]   Time stamp of our file: 2014-09-13 21:14:36.000
[10:47:44.600]   Dest file exists.
[10:47:44.601]   Time stamp of existing file: 2002-07-10 10:33:02.000
[10:47:44.603]   Version of our file: (none)
[10:47:44.609]   Version of existing file: (none)
[10:47:44.611]   Installing the file.
[10:47:44.637]   Successfully installed the file.
[10:47:44.640]   -- File entry --
[10:47:45.603]   Dest filename: C:\Users\Public\MyCompany\MyProgDocs
[10:47:45.606]   Time stamp of our file: 2014-09-16 14:51:26.000
[10:47:45.608]   Dest file exists.
[10:47:45.610]   Time stamp of existing file: 2014-09-13 21:14:36.000
[10:47:45.612]   Version of our file: (none)
[10:47:45.615]   Version of existing file: (none)
[10:47:45.617]   Installing the file.
[10:47:45.710]   Successfully installed the file.

如您所见,我的 3 个 PDF 文件中的每一个都已复制到一个名为 C:\Users\Public\MyCompany\MyProgDocs 的文件中,而不是我想要的 C:\Users\Public\MyCompany\MyProgDocs\doc 1.pdf 等。目标文件由 [Files] 部分的第一行创建,然后被第二行覆盖,第三行再次覆盖。

通过调试器,我看到我的 Pascal 脚本和支持它的 DLL 工作正常。

调用DocPath(s)返回字符串中的字符数,并将其参数s设置为我想要的字符串值。在 XP 上,它返回一个零并将s 设置为空字符串。在 Windows 7 上,DocPath(s) 返回 36 并将 s 设置为 C:\Users\Public\MyCompany\MyProgDocs

我该如何解决这个问题?

编辑: 以下是我的 DLL 中的一些相关代码:

#define FOLDERNAME _T("MyCompany")
static CString GetPublicPath()
{
    TCHAR pubpath[_MAX_PATH] = {_T("")};
    int nameSize = ::GetEnvironmentVariable(_T("public"), pubpath, countof(pubpath));
    if (0 < nameSize)
    {
        TCHAR* wdbuf = _tgetcwd(NULL, 0);
        _tchdir(pubpath);
        _tmkdir(FOLDERNAME);
        _tchdir(FOLDERNAME);
        _tcscat(pubpath, _T("\\"));
        _tcscat(pubpath, FOLDERNAME);
        _tchdir(wdbuf);
        free(wdbuf);
    }

    return CString(pubpath);
}
int STDCALL DocPath(wchar_t** x)
{
    CString docpath = GetPublicPath();
    docpath = StripBackslash(docpath);
    if (0 < docpath.GetLength())
    {
        docpath += _T("\\MyProgDocs");
    }
    _tcscpy(*x, docpath.GetBuffer());
    ::MessageBox(0, *x, _T("DLL DocPath()"), MB_OK);
    return _tcslen(*x);
}

我没有在生产版本中调用MessageBox(),但它对调试很有用。宏 countof 类似于 sizeof,但返回的是数组计数而不是字节大小,因此它适用于宽字符。

【问题讨论】:

  • DocPath函数有什么作用?
  • DocPath() 检查环境变量 Public(如果存在)以获取公用文件夹的路径。
  • 作为副作用,DocPath() 调用的GetPublicPath() 也会在 Windows 7 中创建目标目录,但不是 XP。我现在想知道这是否是问题所在,并将进一步调查。
  • 我修改了GetPublicPath(),使其不创建目标目录;它只是获得路径。这没有任何区别。 Inno Setup 在复制我的 PDF 文件时仍然不会附加文档名称。
  • 你可以扩展{userdocs}常量,结果是一样的。

标签: windows inno-setup


【解决方案1】:

如果 k > 0,您必须将 s 的长度设置为 k。 但是从 inno 获取环境变量要容易得多(并且不需要编写 dll) - 例如:

function DocumentFolder(dummy: String): String;
var
  s: String;
begin
  s := GetEnv('public');
  if Length(s) > 0 then
     s := s + '\MyCompany\MyProgDocs'
  else
    s := ExpandConstant('{app}');
  Result := s;
end;

【讨论】:

  • 谢谢!那会做得很好!
猜你喜欢
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多