如何在 Pascal Script/Inno 安装程序中使用 WinAPI 中的 PathCombine()?
How do I use PathCombine() from WinAPI in Pascal Script/Inno Setup?
我正在尝试了解如何使用 Pascal Script/Inno 安装程序中的 WinAPI 函数。我没有找到太多代码示例如何去做,而且我不是 Pascal 程序员。这是我到目前为止所做的:
正在导入函数
function PathCombine (
pszPathOut : PChar;
pszPathIn : PChar;
pszMore : PChar
) : PChar;
external 'PathCombineA@Shlwapi.dll stdcall';
并像这样使用它:
function InitializeSetup(): Boolean;
var
a, b,c : PChar;
s : string;
begin
SetLength(s, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
c := PathCombine(s, a, b);
MsgBox(s, mbInformation, MB_OK);
end;
输出是这样的:
预期输出为:
C:\one\two
我很确定我正在访问内存中的垃圾值,但我不知道为什么,我该如何解决这个问题?
我认为(虽然我有一段时间没有使用 Pascal/Delphi)问题是C "strings" (char *
) 基于 0 索引,而 Pascal 字符串是基于 1 索引的(字节 0 用于存储长度)。
因此,如果您将 s
变量声明为:
s: array[0..255] of Char; //Don't forget to change it to MAX_PATH afterwards
应该可以。也可以像这样使用 PathCombine
函数:
PathCombine(s, a, b);
无需将其结果(与 s
相同)分配给另一个变量(无论如何您都不会使用)。
您没有指定您使用的是 Ansi 还是 Unicode 版本的 Inno Setup。
但这应该适用于任一版本:
function PathCombine(
pszPathOut : PAnsiChar;
pszPathIn : PAnsiChar;
pszMore : PAnsiChar
) : PAnsiChar; external 'PathCombineA@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: AnsiString;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
尽管我强烈建议您改用 Unicode version of Inno Setup 和 PathCombineW
。
function PathCombine(
pszPathOut : string;
pszPathIn : string;
pszMore : string
) : Cardinal; external 'PathCombineW@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: string;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
请注意,Inno Setup 缺少 PWideChar
类型。虽然它可以将 string
编组到 LPTSTR
(PWideChar
) 函数参数,但它不能编组 LPTSTR
return 值。所以我使用 Cardinal
作为 return 类型。它与指针(指向 char)具有相同的大小,因此堆栈将匹配。我们实际上并不需要 returned 值。
我正在尝试了解如何使用 Pascal Script/Inno 安装程序中的 WinAPI 函数。我没有找到太多代码示例如何去做,而且我不是 Pascal 程序员。这是我到目前为止所做的:
正在导入函数
function PathCombine (
pszPathOut : PChar;
pszPathIn : PChar;
pszMore : PChar
) : PChar;
external 'PathCombineA@Shlwapi.dll stdcall';
并像这样使用它:
function InitializeSetup(): Boolean;
var
a, b,c : PChar;
s : string;
begin
SetLength(s, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
c := PathCombine(s, a, b);
MsgBox(s, mbInformation, MB_OK);
end;
输出是这样的:
预期输出为:
C:\one\two
我很确定我正在访问内存中的垃圾值,但我不知道为什么,我该如何解决这个问题?
我认为(虽然我有一段时间没有使用 Pascal/Delphi)问题是C "strings" (char *
) 基于 0 索引,而 Pascal 字符串是基于 1 索引的(字节 0 用于存储长度)。
因此,如果您将 s
变量声明为:
s: array[0..255] of Char; //Don't forget to change it to MAX_PATH afterwards
应该可以。也可以像这样使用 PathCombine
函数:
PathCombine(s, a, b);
无需将其结果(与 s
相同)分配给另一个变量(无论如何您都不会使用)。
您没有指定您使用的是 Ansi 还是 Unicode 版本的 Inno Setup。
但这应该适用于任一版本:
function PathCombine(
pszPathOut : PAnsiChar;
pszPathIn : PAnsiChar;
pszMore : PAnsiChar
) : PAnsiChar; external 'PathCombineA@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: AnsiString;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
尽管我强烈建议您改用 Unicode version of Inno Setup 和 PathCombineW
。
function PathCombine(
pszPathOut : string;
pszPathIn : string;
pszMore : string
) : Cardinal; external 'PathCombineW@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: string;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
请注意,Inno Setup 缺少 PWideChar
类型。虽然它可以将 string
编组到 LPTSTR
(PWideChar
) 函数参数,但它不能编组 LPTSTR
return 值。所以我使用 Cardinal
作为 return 类型。它与指针(指向 char)具有相同的大小,因此堆栈将匹配。我们实际上并不需要 returned 值。