如果我的代码很糟糕,请道歉。我遇到此错误消息:
安装程序当前以非管理员用户身份启动,然后在文件开始复制之前以管理员用户身份终止并重新启动。只有当注册'注册时才会出现错误消息。选择安装。
如果我在安装位置输入任何顶级驱动器,则会发生这种情况。如果我在网络共享上输入一个文件夹,我将得到一个不同的错误(另一个权限问题),如果我在C:\驱动器上输入一个文件夹(如在C:\ xyz中),那么它可以正常工作。 / p>
#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;
答案 0 :(得分:0)
事实证明,问题在于
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);
在此部分代码中,将使用管理权限重新启动启动程序。在PARAMS SECTION中,'/ DIR'选项是Inno Setup选项,它会覆盖默认的InstallDirectory。这需要设置为不是顶级驱动器(即不是'C:\'或'O:\',而是'C:\ xyz')。
只要改变了,上述程序存根就可以正常工作。