全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1786
推到 Plurk!
推到 Facebook!

如何更新一些正在使用的 dll 檔

尚未結案
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-14 20:07:05 IP:218.16.xxx.xxx 未訂閱
當使用一些安裝軟件要更新一些使用中的檔案時,雖然不能直接更新,但能在重新啟動系統時自動更新。 請問甚樣可以用 Delphi 和 Windows API 在我們自己的程式內達到這個效果呢? 謝謝。
huwk
資深會員


發表:26
回覆:340
積分:323
註冊:2002-04-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-14 21:35:34 IP:211.76.xxx.xxx 未訂閱
有個想法.. 將那些dll放到一個暫存區中.. 且寫一個一執行就能copy那些檔案到特定目錄的執行檔.. 在RunOnce機碼內寫入這個執行檔的資訊.. 只要一重新開機即可.. 這種方式在一些反安裝程式內常見.. 只是他是用來解除安裝而己..
------
熊的學習 http://huwk.blogspot.com
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-14 23:17:52 IP:218.16.xxx.xxx 未訂閱
謝謝你的建議。 反安裝是一個程式加一個 filelist 檔案沒錯,但安裝應有更直接的方法罷...
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊:2002-07-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-14 23:56:49 IP:61.59.xxx.xxx 未訂閱
Justmade 兄,給您個方向 安裝程式 Inno Setup 裡有此功能,它是Open source  所以,看它的程式碼,您應會有收獲 裡面有段code 應該是你要的 inno setup 3.0.6 source http://www.jrsoftware.org/files/site1ftp/issrc.zip 裡面的RegSrv.dpr 裡有呼叫到InstFunc.pas裡的RestartReplace 功能 詳細的部份看看它的code 吧    
procedure RestartReplace (const TempFile, DestFile: String);
{ Renames TempFile to DestFile the next time Windows is started. If DestFile
  already existed, it will be overwritten. If DestFile is '' then TempFile
  will be deleted, however this is only supported by 95/98 and NT, not
  Windows 3.1x. }
var
  WinDir, WinInitFile, TempWinInitFile: String;
  OldF, NewF: TextFile;
  OldFOpened, NewFOpened: Boolean;
  L, L2: String;
  RenameSectionFound, WriteLastLine: Boolean;
  NewDestFile: PChar;
begin
  if not UsingWinNT then begin
    { Because WININIT.INI allows multiple entries with the same name,
      it must manually parse the file instead of using
      WritePrivateProfileString }
    WinDir := GetWinDir;
    WinInitFile := AddBackslash(WinDir) + 'WININIT.INI';
    OldFOpened := False;
    NewFOpened := False;
    try
      try
        if NewFileExists(WinInitFile) then begin
          TempWinInitFile := GenerateUniqueName(WinDir, '.tmp');
          { Flush Windows' cache for the file first }
          WritePrivateProfileString (nil, nil, nil, PChar(WinInitFile));
          AssignFile (OldF, WinInitFile);
          FileMode := fmOpenRead or fmShareDenyWrite;  Reset (OldF);
          OldFOpened := True;
        end
        else
          TempWinInitFile := WinInitFile;
        AssignFile (NewF, TempWinInitFile);
        FileMode := fmOpenWrite or fmShareExclusive;  Rewrite (NewF);
        NewFOpened := True;
        RenameSectionFound := False;
        WriteLastLine := False;
        if OldFOpened then
          while not Eof(OldF) do begin
            Readln (OldF, L);
            WriteLastLine := True;
            L2 := Trim(L);
            if (L2 <> '') and (L2[1] = '[') then begin
              if CompareText(L, '[rename]') = 0 then
                RenameSectionFound := True
              else
              if RenameSectionFound then
                Break;
            end;
            Writeln (NewF, L);
            WriteLastLine := False;
          end;
        if not RenameSectionFound then
          Writeln (NewF, '[rename]');
        if DestFile <> '' then
          L2 := GetShortName(DestFile)
        else
          L2 := 'NUL';
        Writeln (NewF, L2 + '=' + GetShortName(TempFile));
        if OldFOpened then begin
          if WriteLastLine then
            Writeln (NewF, L);
          while not Eof(OldF) do begin
            Readln (OldF, L);
            Writeln (NewF, L);
          end;
        end;
      finally
        if NewFOpened then CloseFile (NewF);
        if OldFOpened then CloseFile (OldF);
      end;
    except
      if OldFOpened then DeleteFile (TempWinInitFile);
      raise;
    end;
    if OldFOpened then begin
      if not DeleteFile(WinInitFile) then
        Win32ErrorMsg ('DeleteFile');
      if not MoveFile(PChar(TempWinInitFile), PChar(WinInitFile)) then
        Win32ErrorMsg ('MoveFile');
    end;
  end
  else begin
    if DestFile <> '' then
      NewDestFile := PChar(DestFile)
    else
      NewDestFile := nil;
    
    if not MoveFileEx(PChar(TempFile), NewDestFile,
       MOVEFILE_DELAY_UNTIL_REBOOT or MOVEFILE_REPLACE_EXISTING) then
      Win32ErrorMsg ('MoveFileEx');
  end;
end;
發表人 - ddy 於 2003/04/15 00:23:33
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-15 13:58:11 IP:218.16.xxx.xxx 未訂閱
謝謝回答,令我得益不少。不單是本題答案,還有這個我之前沒用的 inno setup。    我剛用 Delphi 7 附的新版 Install Express 試做一個 Setup 檔,初步感覺是很華麗很多功能...都不能用,但我將兩個檔案(共
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-15 14:18:56 IP:218.16.xxx.xxx 未訂閱
補充一下給以後找資料的人。 1. 要用這個先決條件是將 File 以另一名字(就是傳入的 TempFile 參數) 存好。 2. 最簡單的做法就是紅色的部份 MoveFileEx,但這個功能不支援 95/98/Me,所以要前面的一大段來說理 95系列。 3. 在 95系列的方法簡單來說就是在 WinInit.ini Rename 段 加入 DestFile=SourcesFile 的字句。
系統時間:2024-05-05 22:20:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!