“您必须输入带有驱动程序的完整路径或格式为...的UNC路径." Inno Setup错误消息 [英] "You must enter a full path with driver [...] or a UNC path in the form ..." inno setup error message

查看:248
本文介绍了“您必须输入带有驱动程序的完整路径或格式为...的UNC路径." Inno Setup错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,我的代码很糟糕.我遇到此错误消息:

Apologies if my code is terrible. I am running into this error message:

安装程序当前以非管理员用户身份启动,然后在开始复制文件之前以管理员用户身份杀死并重新启动自身.仅在选择注册"安装时出现错误消息.

The installer currently starts as a non-admin user then kills and restarts itself as an admin user right before files start being copied. The error message only comes up when 'Register' install is selected.

如果我在安装位置输入任何顶级驱动器,就会发生这种情况.如果我在网络共享上输入一个文件夹,则会遇到另一个错误(另一个特权问题),并且如果我在C:\驱动器上输入一个文件夹(如在C:\ xyz中),那么它将正常工作.

This occurs if I enter any top-level drive in the install location. If I enter a folder on a network share, I'll get a different error (another privilege issue) and if I input a folder on the C:\ drive (as in C:\xyz) then it works fine.

#define MyAppName "O"
#define MyAppVersion "0.0"

[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.)
AppId={{9BB6F4FD-5530-4043-BD9E-A405BAEDDDFF}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
DefaultDirName={sd}\{#MyAppName}
DisableDirPage=yes
AllowNoIcons=yes
OutputDir={desktop}
OutputBaseFilename=dummy
Compression=lzma
SolidCompression=yes

PrivilegesRequired=lowest

[Types]
Name: "server"; Description: "Odin Server Install"
Name: "client"; Description: "Odin Register/Workstation Install"

[Components]
Name: "data_shared_exe"; Description: "Core apps installed"; Types: server;
Name: "C_Odin"; Description: "Database stuff"; Types: server client;
Name: "shortcuts"; Description: "Shortcuts to Odin apps"; Types: server client;

[Code]

var
  SelectOdinSharePage: TInputDirWizardPage;
  SelectOdinInstallPage: TInputDirWizardPage;

  Elevated: Boolean;
  InstallType: Integer;
  DirParam: string;

type
  HINSTANCE = THandle;

// Privilege Escalation code
// Inspired by/Courtesy of http://stackoverflow.com/questions/21556853/make-inno-setup-installer-request-privileges-elevation-only-when-needed
procedure ExitProcess(uExitCode: UINT);
  external 'ExitProcess@kernel32.dll stdcall';
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
  lpParameters: string; lpDirectory: string; nShowCmd: Integer): HINSTANCE;
  external 'ShellExecuteW@shell32.dll stdcall';

function IsServerInstall(): Boolean;
begin
  Result := (InstallType=0)
end;

function CmdLineParamExists(const Value: string): Boolean;
var
  I: Integer;  
begin
  Result := False;
  for I := 1 to ParamCount do
    if CompareText(ParamStr(I), Value) = 0 then
    begin
      Result := True;
      Exit;
    end;
end;

function CmdLineParamReadInt(const Value: string): integer;
var
  I: Integer;  
begin
  Result := -1;
  for I := 1 to ParamCount do
    if Pos(Value, ParamStr(I)) = 1 then
    begin
      Result := StrToInt(Copy(ParamStr(I), Length(Value)+2, 1));
      //MsgBox(Format('ReadInt: %s', [Copy(ParamStr(I), Length(Value)+2, 1)]), mbInformation, MB_OK);
      Exit;
    end;
end;

function CmdLineParamReadStr(const Value: string): string;
var
  I: Integer;  
begin
  Result := '';
  for I := 1 to ParamCount do
    if Pos(Value, ParamStr(I)) = 1 then
    begin
      Result := Copy(ParamStr(I), Length(Value)+2, Length(ParamStr(I))-Length(Value)-1);
      //MsgBox(Format('ReadStr: %s',[Result]), mbInformation, MB_OK)
      Exit;
    end;
end;

procedure OnTypeChange(Sender: TObject);
begin
  // set the item index in hidden TypesCombo
  WizardForm.TypesCombo.ItemIndex := TNewRadioButton(Sender).Tag;
  InstallType := TNewRadioButton(Sender).Tag;
  // notify TypesCombo about the selection change
  WizardForm.TypesCombo.OnChange(nil);
end;

procedure InitializeWizard();
var
  I: Integer;
  RadioButton: TNewRadioButton;
begin
  // By default, InstallType is 1 ('Register')
  InstallType := 1;

  // Privilege escalation parameters
  Elevated := CmdLineParamExists('/ELEVATE');
  if Elevated then
  begin
    InstallType := CmdLineParamReadInt('/INSTALLTYPE');
    DirParam := CmdLineParamReadStr('/DIR');
    //MsgBox(Format('DirParam: %s', [DirParam]), mbInformation, MB_OK);
  end;

  for I := 0 to WizardForm.TypesCombo.Items.Count - 1 do
  begin
    // create radio button and set the basic properties
    RadioButton := TNewRadioButton.Create(WizardForm);
    RadioButton.Parent := WizardForm.SelectComponentsPage;
    RadioButton.Left := WizardForm.TypesCombo.Left;
    RadioButton.Top := WizardForm.TypesCombo.Top + I * RadioButton.Height;
    RadioButton.Width := WizardForm.TypesCombo.Width;
    // the Tag property substitutes the index property
    RadioButton.Tag := I;
    RadioButton.TabOrder := I;     
    RadioButton.OnClick := @OnTypeChange;
    // check just the first item
    RadioButton.Checked := I = InstallType;
    RadioButton.Caption := WizardForm.TypesCombo.Items[I];
  end;
  // hide the TypesCombo combo box
  WizardForm.TypesCombo.Visible := False;

  SelectOdinSharePage := CreateInputDirPage(wpSelectComponents,
  'Select Odin Exe''s directory', 'Where are the Odin exe''s located?',
  'The Odin exe''s are usually located on the Odin Network Share under "exe" or "exes". ' +
  'Once you have found this directory, click Next. If you would like to select a different folder, click Browse.',
  False, 'New Folder');
  SelectOdinSharePage.Add('');
  SelectOdinSharePage.Values[0] := 'O:';

  SelectOdinInstallPage := CreateInputDirPage(wpSelectComponents,
  'Select Odin Install directory', 'Select where to install Odin core apps',
  'To continue, click Next. If you would like to select a different folder, click Browse.',
  False, 'New Folder');
  SelectOdinInstallPage.Add('');
  SelectOdinInstallPage.Values[0] := 'C:\Program Files (x86)\Odin';

  if Elevated then
  begin
    if IsServerInstall() then SelectOdinInstallPage.Values[0] := DirParam;
    if not IsServerInstall() then SelectOdinSharePage.Values[0] := DirParam;
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := False;
  if ((PageID=100) and IsServerInstall()) then Result := True;
  if ((PageID=101) and not IsServerInstall()) then Result := True;

  if Elevated then
  begin
    if IsServerInstall() then
    begin
      if ((PageID=7) or (PageID=101)) then Result := True;
    end;
    if InstallType=1 then
    begin
      if ((PageID=7) or (PageID=100)) then Result := True;
    end;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  Params: string;
  RetVal: HINSTANCE;
begin
  Result := True;
  //MsgBox(Format('Is Server Install: %d', [WizardForm.TypesCombo.ItemIndex]), mbInformation, MB_OK);
  if (CurPageID=101) and IsServerInstall() then
  begin
    Params := ExpandConstant('/DIR="' + SelectOdinInstallPage.Values[0] + '" /ELEVATE /INSTALLTYPE=0');
    RetVal := ShellExecute(WizardForm.Handle, 'runas',
      ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
    if RetVal > 32 then
    begin
      ExitProcess(0);
    end
    else
      MsgBox('Administrative privilege escalation failed. Install aborted. Contact Odin Support.', mbInformation, MB_OK);
      ExitProcess(0);
  end;
  if (CurPageID=100) and (not IsServerInstall()) then
  begin
    Params := ExpandConstant('/DIR="' + SelectOdinSharePage.Values[0] + '" /ELEVATE /INSTALLTYPE=1');

    RetVal := ShellExecute(WizardForm.Handle, 'runas',
      ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
    if RetVal > 32 then
    begin
      ExitProcess(0);
    end
    else
      MsgBox('Administrative privilege escalation failed. Install aborted. Contact Odin Support.', mbInformation, MB_OK);
      ExitProcess(0);
  end;
end;

推荐答案

事实证明,问题出在行上

As it turns out, the problem lies in the lines

if (CurPageID=100) and (not IsServerInstall()) then
  begin
    Params := ExpandConstant('/DIR="' + SelectOdinSharePage.Values[0] + '" /ELEVATE /INSTALLTYPE=1');

    RetVal := ShellExecute(WizardForm.Handle, 'runas',
      ExpandConstant('{srcexe}'), Params, '', SW_SHOW);

在此代码部分中,将使用管理特权重新启动启动器.在参数部分,"/DIR"选项是Inno Setup选项,它将覆盖默认的InstallDirectory.需要将其设置为非顶级驱动器(即不是"C:\"或"O:\",而是"C:\ xyz").

In this section of code, the launcher is re-launched with administrative privileges. IN THE PARAMS SECTION, the '/DIR' option is an Inno Setup option, which overrides the default InstallDirectory. This needs to be set to something that is not a top-level drive (i.e., not 'C:\' or 'O:\', but 'C:\xyz').

只要更改,上面的程序存根就可以正常工作.

As long as that is changed, the above program stub will work fine.

这篇关于“您必须输入带有驱动程序的完整路径或格式为...的UNC路径." Inno Setup错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆