Inno Setup:允许用户只选择可以安装软件的驱动器?

时间:2014-02-18 21:44:26

标签: inno-setup

我可以允许用户只选择安装软件的驱动器吗?

例如,他们可以选择C或D驱动器:

C:\软件

d:\软件

但是用户无法指定其他任何内容,

就像他们无法选择在Downloads或MyDocumnets等下安装软件。

这可能吗?

1 个答案:

答案 0 :(得分:11)

如何限制用户仅选择将安装软件的驱动器?

设计这种限制的方法有很多种。我选择了一个创建组合框的组合框,其中包含用户可以选择的可用路径。此代码首先列出机器上的所有固定驱动器,如果至少有一个,则创建放置的组合框而不是原始目录选择控件。它填充了驱动器名称,后跟一个取自DefaultDirName指令值的固定目录,该值不能包含驱动器部分,因为它已经与找到的固定驱动器根连接:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName=My Program

[Messages]
SelectDirBrowseLabel=To continue, click Next.

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif
type
  TDriveType = (
    dtUnknown,
    dtNoRootDir,
    dtRemovable,
    dtFixed,
    dtRemote,
    dtCDROM,
    dtRAMDisk
  );
  TDriveTypes = set of TDriveType;

function GetDriveType(lpRootPathName: string): UINT;
  external 'GetDriveType{#AW}@kernel32.dll stdcall';
function GetLogicalDriveStrings(nBufferLength: DWORD; lpBuffer: string): DWORD;
  external 'GetLogicalDriveStrings{#AW}@kernel32.dll stdcall';

var
  DirCombo: TNewComboBox;

#ifndef UNICODE
function IntToDriveType(Value: UINT): TDriveType;
begin
  Result := dtUnknown;
  case Value of
    1: Result := dtNoRootDir;
    2: Result := dtRemovable;
    3: Result := dtFixed;
    4: Result := dtRemote;
    5: Result := dtCDROM;
    6: Result := dtRAMDisk;
  end;
end;
#endif

function GetLogicalDrives(Filter: TDriveTypes; Drives: TStrings): Integer;
var
  S: string;
  I: Integer;
  DriveRoot: string;
begin
  Result := 0;

  I := GetLogicalDriveStrings(0, #0);
  if I > 0 then
  begin
    SetLength(S, I);
    if GetLogicalDriveStrings(Length(S), S) > 0 then
    begin
      S := TrimRight(S) + #0;
      I := Pos(#0, S);
      while I > 0 do
      begin
        DriveRoot := Copy(S, 1, I - 1);
        #ifdef UNICODE
        if (Filter = []) or
          (TDriveType(GetDriveType(DriveRoot)) in Filter) then
        #else
        if (Filter = []) or
          (IntToDriveType(GetDriveType(DriveRoot)) in Filter) then
        #endif
        begin
          Drives.Add(DriveRoot);
        end;
        Delete(S, 1, I);
        I := Pos(#0, S);
      end;
      Result := Drives.Count;
    end;
  end;
end;

procedure DriveComboChange(Sender: TObject);
begin
  WizardForm.DirEdit.Text := DirCombo.Text;
end;

procedure InitializeWizard;
var
  I: Integer;
  StringList: TStringList;
begin
  StringList := TStringList.Create;
  try
    if GetLogicalDrives([dtFixed], StringList) > 0 then
    begin
      WizardForm.DirEdit.Visible := False;
      WizardForm.DirBrowseButton.Visible := False;

      DirCombo := TNewComboBox.Create(WizardForm);
      DirCombo.Parent := WizardForm.DirEdit.Parent;
      DirCombo.SetBounds(WizardForm.DirEdit.Left, WizardForm.DirEdit.Top,
        WizardForm.DirBrowseButton.Left + WizardForm.DirBrowseButton.Width -
        WizardForm.DirEdit.Left, WizardForm.DirEdit.Height);
      DirCombo.Style := csDropDownList;
      DirCombo.OnChange := @DriveComboChange;

      for I := 0 to StringList.Count - 1 do
        DirCombo.Items.Add(StringList[I] + '{#SetupSetting('DefaultDirName')}');

      DirCombo.ItemIndex := 0;
      DirCombo.OnChange(nil);
    end;
  finally
    StringList.Free;
  end;
end;

截图:

enter image description here