论坛风格切换切换到宽版
  • 4551阅读
  • 6回复

虎版,帮忙解决一个找目录的代码。 [复制链接]

上一主题 下一主题
离线373723699
 

发帖
38
金钱
380
威望
38
只看楼主 正序阅读 0 发表于: 2013-12-19
我的需求是这样的:在卸载安装包的时候,我有一个选择是保留用户配置信息,当选择保留的时候,目录下的几个文件被保留下来,再次安装的时候,我要将软件安装在这个目录下,那些配置文件才能生效,在安装选择目录的界面我希望有下面这个效果。
这段代码如何写?能不能帮忙


在选择一个目录的下面多出一段字     “检测到IAP软件的残留文件目录:E:\IAP" 右边有一个按钮,点击使用该目录后,上面就变成这个目录的位置。
我查看过论坛的以前帖子,你好像说要找到软件的注册表位置,可是我这个是卸载后的,能找到么?还有注册表位置我也不清楚如何找,总感觉是不这样做。
不知道这个方法适不适用我这情况,还是说弄个查询检测文件的代码比较合适?
我附上我的DEMO代码,麻烦了,或者虎版有什么更好的建议,可以教教我。 新建文件夹.zip (5 K) 下载次数:5
我用的是增强版,可以直接写我代码里,按钮什么的。




离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 6 发表于: 2013-12-20

; 脚本用 Inno Setup 脚本向导 生成。
; 查阅文档获取创建 INNO SETUP 脚本文件的详细资料!

#define MyAppName "我的程序"
#define MyAppVersion "1.5"
#define MyAppPublisher "我的公司"
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"

[Setup]
; 注意: AppId 的值是唯一识别这个程序的标志。
; 不要在其他程序中使用相同的 AppId 值。
; (在编译器中点击菜单“工具 -> 产生 GUID”可以产生一个新的 GUID)
AppId={{E50FAF95-CBC8-44AC-9E68-A1FA0CF1891B}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDirName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
DirExistsWarning=no

[Languages]
Name: "default"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "IAP\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "IAP\IAPdata\DelDParam.ini"; DestDir: "{app}\IAPdata"; Flags: uninsneveruninstall
Source: "IAP\IAPplant\localParam.ini"; DestDir: "{app}\IAPplant"; Flags: uninsneveruninstall

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Registry]
Root: HKCU; Subkey: "Software\IAP"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"

[Code]
var
  FoundOldPath: boolean;
  OldPath: string;
  NewStaticText1: TNewStaticText;

procedure NewDirEditOnChange(Sender: TObject);
begin
  if not FoundOldPath then
    NewStaticText1.Caption := ''
  else
    if WizardForm.DirEdit.Text = OldPath then
      NewStaticText1.Caption := '提示:该目录中保存有上次使用后留下的用户配置文件,建议您继续使用该目录。'
    else
      NewStaticText1.Caption := '提示:在目录 '+ OldPath +' 中保存有上次使用后留下的用户配置文件,建议您将软件安装到该目录。';
end;

procedure CheckOldPath;
var
  sDir: string;
begin
  FoundOldPath := false;
  OldPath := '';
  if RegQueryStringValue(HKCU, 'Software\IAP', 'InstallPath', sDir) then
    begin
      FoundOldPath := true;
      OldPath := sDir;
    end;
end;

function GetDirName(Param: String): String;
begin
  if FoundOldPath then
    Result := OldPath
  else
    Result := ExpandConstant('{sd}\IAP');
end;

function InitializeSetup(): Boolean;
begin
  CheckOldPath;
  Result:= true;
end;

procedure InitializeWizard();
begin
  NewStaticText1 := TNewStaticText.Create(WizardForm);
  with NewStaticText1 do
  begin
    Parent := WizardForm.SelectDirPage;
    if FoundOldPath then
      Caption := '提示:该目录中保存有上次使用后留下的用户配置文件,建议您继续使用该目录。'
    else
      Caption := '';
    Left := ScaleX(0);
    Top := ScaleY(102);
    Width := ScaleX(410);
    Height := ScaleY(30);
    WordWrap:= true;
  end;
WizardForm.DirEdit.OnChange := @NewDirEditOnChange;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then
    if MsgBox('您是否要保留用户配置信息?', mbConfirmation, MB_YESNO) = IDNO then
//删除 {app} 文件夹及其中所有文件
      begin
        DelTree(ExpandConstant('{app}'), True, True, True);
        RegDeleteKeyIncludingSubkeys(HKCU, 'Software\IAP');
      end;
end;
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 5 发表于: 2013-12-20
第一个问题:默认安装目录是在这里设定的:
Result := ExpandConstant('{pf}\IAP');
你可以根据情况进行调整。不过,设置为 D:\IAP 是不合适的,因为用户可能根本就没有 D: 盘。建议你用
Result := ExpandConstant('{sd}\IAP');
这样根据用户的具体系统情况,可能是 C:\IAP,可能是 D:\IAP 等等。
离线373723699

发帖
38
金钱
380
威望
38
只看该作者 4 发表于: 2013-12-20
回 3楼(gnatix) 的帖子
今天测试了下,基本可以实现功能,但是有几处问题,
第一个问题:



我的软件是要有一个默认的目录,是D:\IAP,当代码设置成DefaultDirName={code:GetDirName}时,默认的位置变了,改怎么设置?
第二个问题:

当再次安装时,检测是位置,并成功提示,这部分没有问题。可以实现。但是这个提示会一直出现在下方,无论当你调整目录位置时,这个我想让他跟着目录位置变化,当你不选择有残留文件的目录时,这行文字就不显示,该怎么改?
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 3 发表于: 2013-12-20
供参考

; 脚本用 Inno Setup 脚本向导 生成。
; 查阅文档获取创建 INNO SETUP 脚本文件的详细资料!

#define MyAppName "我的程序"
#define MyAppVersion "1.5"
#define MyAppPublisher "我的公司"
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"

[Setup]
; 注意: AppId 的值是唯一识别这个程序的标志。
; 不要在其他程序中使用相同的 AppId 值。
; (在编译器中点击菜单“工具 -> 产生 GUID”可以产生一个新的 GUID)
AppId={{E50FAF95-CBC8-44AC-9E68-A1FA0CF1891B}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDirName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
DirExistsWarning=no

[Languages]
Name: "default"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "IAP\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "IAP\IAPdata\DelDParam.ini"; DestDir: "{app}\IAPdata"; Flags: uninsneveruninstall
Source: "IAP\IAPplant\localParam.ini"; DestDir: "{app}\IAPplant"; Flags: uninsneveruninstall

; 注意: 不要在任何共享的系统文件使用 "Flags: ignoreversion"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Registry]
Root: HKCU; Subkey: "Software\IAP"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"

[Code]
var
  FoundOldPath: boolean;
  OldPath: string;


procedure CheckOldPath;
var
  sDir: string;
begin
  FoundOldPath := false;
  OldPath := '';
  if RegQueryStringValue(HKCU, 'Software\IAP', 'InstallPath', sDir) then
    begin
      FoundOldPath := true;
      OldPath := sDir;
    end;
end;


function GetDirName(Param: String): String;
begin
  if FoundOldPath then
    Result := OldPath
  else
    Result := ExpandConstant('{pf}\IAP');
end;

function InitializeSetup(): Boolean;
begin
  CheckOldPath;
  Result:= true;
end;

procedure InitializeWizard();
var
  NewStaticText1: TNewStaticText;
begin
  NewStaticText1 := TNewStaticText.Create(WizardForm);
  with NewStaticText1 do

  begin
    Parent := WizardForm.SelectDirPage;
    if FoundOldPath then
      Caption := '提示:该目录中保存有上次使用后留下的用户配置文件,建议您继续将软件安装到该目录。'
    else
      Caption := '';
    Left := ScaleX(0);
    Top := ScaleY(102);
    Width := ScaleX(400);
    Height := ScaleY(30);
    WordWrap:= true;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then
    if MsgBox('您是否要保留用户配置信息?', mbConfirmation, MB_YESNO) = IDNO then
//删除 {app} 文件夹及其中所有文件
      begin
        DelTree(ExpandConstant('{app}'), True, True, True);
        RegDeleteKeyIncludingSubkeys(HKCU, 'Software\IAP');
      end;
end;

离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 2 发表于: 2013-12-19
你不需要增加新的按钮。如果你按上面说的检查到有上次的残余文件,你直接把这个地方作为新的安装目录的建议就行了。
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 1 发表于: 2013-12-19
检测文件的方式不可取。因为这个会花很长时间,而且可能出现误解,比如用户可能的确完全卸载了,但是他可能只是为了备份自己把某些文件复制到了某个地方,如果你自动检测到这里地方来作为安装目录,这个就不合适了。
建议你在注册表中记录下保存你那个软件的设置的位置。卸载时如果用户选择完全卸载,那么你就把这个记录也删除掉,如果用户选择保留设置,那么你就不删除该注册表记录。下次安装程序只要检查注册表中是否有这个记录就行了。