通过引用将变量从Inno安装程序传递到PowerShell脚本以检索结果

通过引用将变量从Inno安装程序传递到PowerShell脚本以检索结果,powershell,inno-setup,pascalscript,Powershell,Inno Setup,Pascalscript,我正在尝试通过引用将error和error\u msg变量传递给PowerShell脚本。但它不起作用。它不反映在checkHost.ps1中所做的更改 var 错误消息:字符串; 错误:字符串; ok:字符串; 函数NextButtonClick(CurPageID:Integer):布尔值; 开始 错误消息:=“一切正常”; 结果:=真; 错误:='false'; 确定:=‘正确’; exec('powershell.exe', “-noexit-executionpolicy旁路”+ “'

我正在尝试通过引用将
error
error\u msg
变量传递给PowerShell脚本。但它不起作用。它不反映在
checkHost.ps1
中所做的更改

var
错误消息:字符串;
错误:字符串;
ok:字符串;
函数NextButtonClick(CurPageID:Integer):布尔值;
开始
错误消息:=“一切正常”;
结果:=真;
错误:='false';
确定:=‘正确’;
exec('powershell.exe',
“-noexit-executionpolicy旁路”+
“'D:\Hyperv\u ins\u BM\checkHost.ps1[ref]error[ref]error\u msg”,
ExpandConstant({tmp}')、SW_SHOW、ewwaituntiltered、ResultCode);
终止

有人能帮忙吗?

不可能。PowerShell和其他任何应用程序一样,都是一个普通的控制台应用程序,它不是API


正如@Bill_Steward所建议的,让PowerShell脚本将其结果输出到一个文件中,并在Inno安装程序中读取:

函数CheckHost(var ErrorMessage:string):布尔值;
变量
参数:字符串;
TempPath:字符串;
AErrorMessage:AnsiString;
结果代码:整数;
开始
TempPath:=ExpandConstant('{tmp}\checkHost.err');
参数:=
'-ExecutionPolicy bypass-文件“C:\path\to\script\checkHost.ps1”+
'-ErrorFile“+TempPath+”;
结果:=
Exec('powershell.exe',Parameters',SW_HIDE,ewwaitunfiltered,ResultCode)和
(结果代码=0);
如果没有结果的话
开始
如果LoadStringFromFile(TempPath,AErrorMessage),则
开始
ErrorMessage:=错误消息;
终止
终止
删除文件(临时路径);
终止
以上是基于


使用以下功能:

var
错误消息:字符串;
开始
如果选中主机(错误消息),则
开始
MsgBox('主机检查成功',MB信息,MB_OK);
终止
其他的
开始
MsgBox(错误消息,mbError,MB_OK);
终止
终止

PowerShell脚本可能如下所示:

param(
$errorFile
)
if(checkHost())
{
出口0
}
其他的
{
设置内容-路径$errorFile-值“主机检查因某种原因失败”
出口1
}


不过,正如@Bill_Steward也提到的,很可能您可以在纯Pascal脚本中实现您的检查。但这是一个不同的问题。

我在下面尝试作为示例代码。将创建checkHost.err并在其中添加测试

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT    FILES!

#define PUBLISHER "AtoZ Technology, Inc."
#define PUBLISHER_URL "http://www.xyzabc.com/"
#define PRODUCT_NAME "test"



[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)

AppPublisher={#PUBLISHER}
AppPublisherURL={#PUBLISHER_URL}
AppCopyright=Copyright (C) 2013-2016 {#PUBLISHER}
AppName=test installer
AppId=TestInstaller
AppVerName=Test Installer
DefaultDirName={pf}\Test Install
DefaultGroupName=Test Install
Compression=lzma2
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
OutputBaseFilename=test_installer
OutputDir="D:\Test"
LicenseFile=lics.txt
SetupLogging=yes
VersionInfoProductName=Test  ]

VersionInfoProductTextVersion= "1.0"

[Files]
Source: "checkHost.ps1"; DestDir: "{app}"; Flags: ignoreversion

[Code]
function CheckHost(var ErrorMessage: string): Boolean;
var
Parameters: string;
TempPath: string;
AErrorMessage: AnsiString;
ResultCode: Integer;
begin                                                              
begin
TempPath := ExpandConstant('{tmp}\checkHost.err');
Parameters := '-noexit -ExecutionPolicy bypass -File     "D:\Test\checkHost.ps1" ' + '-errorFile "' + TempPath + '"';
Result :=
Exec('powershell.exe', Parameters, ExpandConstant('{tmp}'), SW_SHOW,   ewWaitUntilTerminated, ResultCode) and
(ResultCode = 0);
if Result then
begin
if LoadStringFromFile(TempPath, AErrorMessage) then
begin
  ErrorMessage := AErrorMessage;
end;
end;
DeleteFile(TempPath);
end;

var
ModelPage: TInputOptionWizardPage;
models: Variant;
model_info: String;
i: Integer;
procedure InitializeWizard;
begin
ModelPage := CreateInputOptionPage(wpWelcome,
'Model Information', '',
'Please specify the model you would like to install, then click Next.',
 True, False);

 for i:= 0 to 2  do
 begin 
  model_info := 'model' + IntToStr(i);
  model_info := model_info + ' ( HDD ' + '10 GB';
  model_info := model_info + ' SSD ' + '2 GB' + ' )';
  ModelPage.Add(model_info);      
 end;

  ModelPage.SelectedValueIndex := 0;
  end;
  var

  model: String;
  ErrorMessage: string;

  function NextButtonClick(CurPageID: Integer): Boolean;
   begin

   Result := True;

   if CurPageID = ModelPage.ID then
    begin
     if CheckHost(ErrorMessage) <> true then
      begin
      MsgBox(ErrorMessage, mbError, MB_OK);
      end;              
    end;

    end;
;由Inno安装脚本向导生成的脚本。
; 有关创建INNO安装脚本文件的详细信息,请参阅文档!
#定义出版商“AtoZ Technology,Inc.”
#定义发布者\u URL“http://www.xyzabc.com/"
#定义产品名称“测试”
[设置]
; 注意:AppId的值唯一标识此应用程序。
; 不要在其他应用程序的安装程序中使用相同的AppId值。
; (要生成新的GUID,请单击工具|在IDE中生成GUID。)
AppPublisher={#PUBLISHER}
AppPublisherURL={#PUBLISHER_URL}
AppCopyright=版权(C)2013-2016{出版商}
AppName=测试安装程序
AppId=TestInstaller
AppVerName=测试安装程序
DefaultDirName={pf}\Test安装
DefaultGroupName=测试安装
压缩=lzma2
架构sallow=x64
体系结构安装64位模式=x64
OutputBaseFilename=测试\安装程序
OutputDir=“D:\Test”
LicenseFile=lics.txt
SetupLogging=是
VersionInfoProductName=测试]
VersionInfo ProductTextVersion=“1.0”
[档案]
来源:“checkHost.ps1”;DestDir:“{app}”;标志:忽略版本
[守则]
函数CheckHost(var ErrorMessage:string):布尔值;
变量
参数:字符串;
TempPath:字符串;
AErrorMessage:AnsiString;
结果代码:整数;
开始
开始
TempPath:=ExpandConstant('{tmp}\checkHost.err');
参数:='-noexit-ExecutionPolicy bypass-File“D:\Test\checkHost.ps1”'+'-errorFile“+TempPath+'”;
结果:=
Exec('powershell.exe',参数,ExpandConstant('{tmp}'),SW_SHOW,ewwaitunFilterminated,ResultCode)和
(结果代码=0);
如果结果是这样的话
开始
如果LoadStringFromFile(TempPath,AErrorMessage),则
开始
ErrorMessage:=错误消息;
终止
终止
删除文件(临时路径);
终止
变量
ModelPage:TInputOptionWizardPage;
型号:变型;
模型信息:字符串;
i:整数;
程序初始化;
开始
ModelPage:=CreateInputOptionPage(wpWelcome,
“模型信息”,
'请指定要安装的型号,然后单击“下一步”。',
正确的,错误的);
对于i:=0到2 do
开始
型号信息:=“型号”+IntToStr(一);
型号信息:=型号信息+'(硬盘驱动器+'10GB';
型号信息:=型号信息+'SSD'+'2GB'+');
ModelPage.Add(模型信息);
终止
ModelPage.SelectedValueIndex:=0;
终止
变量
模型:字符串;
错误消息:字符串;
函数NextButtonClick(CurPageID:Integer):布尔值;
开始
结果:=真;
如果CurPageID=ModelPage.ID,则
开始
如果CheckHost(ErrorMessage)为true,则
开始
MsgBox(错误消息,mbError,MB_OK);
终止
终止
终止

但是LoadStringFromFile()似乎不起作用,因为msgbox()中打印了空值。

为什么需要通过引用传递参数?我在checkHost.ps1中添加了这一点作为第一件事。参数([Parameter(Mandatory=$True,Position=1)][string][ref]$error[Parameter(Mandatory=$True,Position=2)][string][ref]$error\u msg)您可以通过在脚本的命令行上添加参数来传递参数-使用powershell.exe
-文件
参数-通过为什么必须通过引用传递?我需要在这个checkHost.ps1 script.IIRC生成的inno msgbox中打印错误消息唯一的方法是powershell脚本提供错误消息到stdout,PascalScript代码将读取该值。如果确实要显示错误对话框,则应该从PowerShell脚本内部执行。或者,省去PowerShell并用PascalScript实现该代码。我将尝试您建议的方法。谢谢你