2010-04-26 34 views
6

Tôi đang viết một chương trình cập nhật trong Delphi7 sẽ chạy một lần, nhưng cần nhiều tệp để chạy.Tự giải nén chương trình Delphi

Những gì tôi muốn là đạt được:

  1. tài chạy exe
  2. Exe giải nén file, chạy updater
  3. Nếu updater phát hiện và báo lỗi, nhắc nhở người dùng gửi nhật ký trong e-mail
  4. Sau khi cập nhật được chạy, các tệp tạm thời sẽ bị xóa (một số tệp này là dll được chương trình cập nhật sử dụng, vì vậy trình cập nhật phải được đóng trước khi các tệp có thể bị xóa)

Có ai có thể giới thiệu một giải pháp tốt không? Tôi đã nghĩ về việc sử dụng Inno Setup (quá phức tạp cho một nhiệm vụ dễ dàng như vậy) hoặc sử dụng một tập tin zip tự giải nén (nhưng làm thế nào để xóa các tập tin sau đó)?

Cảm ơn!

Trả lời

2

Tôi đang sử dụng tài nguyên cho chương trình cập nhật của mình. tôi đã được biên dịch tài nguyên với brcc32 hơn so với chương trình updater biên dịch. khi chương trình updater chạy tự kiểm tra mọi thứ và viết hoặc cập nhật với những cái mới. nhưng về quá trình này, bạn phải viết đúng, xóa các đặc quyền tại nơi chương trình của bạn chạy.

tôi đang thêm mã mẫu vào bên dưới.

tập tin exe.rc

newprog RCDATA Application.exe 

tập tin makeres.bat

brcc32 exe.rc 

tập tin updater.dpr

{$R exe.res} 

tập tin đơn vị và thủ tục

procedure ExtractRes(resname,fname,ext:string); 
var 
rStream:TResourceStream; 
fStream:TFileStream; 
fNamex:string; 
begin 
fNamex:=ExtractFilePath(Application.ExeName)+fname+'.'+ext; 
if not fileExists(fnamex) then 
begin 
    try 
    rStream:=tresourcestream.Create(hinstance,ResName,RT_rcDATA); 
    fStream := TFileStream.Create(fnamex, fmCreate); 
    fStream.CopyFrom(rStream, 0); 
    finally 
    rStream.Free; 
    fstream.Free; 
    end; 
end; 
end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
var 
apath:string; 
begin 
if Timer1.Enabled then 
    Timer1.Enabled:=false; 
apath:=ExtractFilePath(Application.ExeName); 
lblMesg.Caption:='Backup old version'; 
Application.ProcessMessages; 
if FileExists(apath+'Application_old.bak') then 
    DeleteFile(apath+'Application_old.bak') ; 
while FileExists(apath+'Application.exe') do 
begin 
    RenameFile(apath + 'Application.exe', apath + 'Application_old.bak'); 
    sleep(1); 
    if FileExists(apath+'Application.exe') then 
    begin 
    lblMesg.Caption:='It seems application still running. Waiting for end'; 
    if FileExists(apath+'Application_old.bak') then 
    DeleteFile(apath+'Application_old.bak'); 
    DeleteFile(apath+'Application.exe'); 
    end; 
    Application.ProcessMessages; 
end; 
lblMesg.Caption:='Creating New Version..'; 
Application.ProcessMessages; 
ExtractRes('Application','Application','exe'); 
lblMesg.Caption:='Running New Version...'; 
Application.ProcessMessages; 
WinExec(pchar(apath+'Application.exe'),sw_show); 
Application.ProcessMessages; 
Halt; 
end; 

tôi nghĩ rằng điều này có thể giúp câu hỏi 1,2,3 của bạn. Đối với 4 bạn có thể mở rộng mã.

+0

Xin chào! 1, tôi cần phải giải nén tập tin vào một thư mục tạm thời và chạy chương trình của tôi ở đó. Một số dll cần phải ở trong cùng thư mục với chương trình và nếu chương trình được chạy mà không có quyền quản trị, nó không thể sử dụng thư mục cơ sở để trích xuất các tệp. 2, Chương trình của tôi sử dụng dll để kết nối với cơ sở dữ liệu. Nếu tôi cố gắng xóa dll sau khi bị ngắt kết nối, nó vẫn đang được sử dụng bởi các thành phần DB. Vì vậy, tôi cần phải gọi một chương trình riêng biệt chỉ để xóa các tập tin gây ra tất cả các loại vấn đề – Steve

+0

tôi hiểu. bạn cần độ cao cho vista và 7. nhưng đối với người dùng giới hạn xp standart bạn cần nhắc người dùng chạy với tư cách quản trị viên. Tôi không biết xp soluiton, nhưng tôi biết bạn phải chạy quá trình từ bên trong mã của bạn một lần nữa với shellexecuteex. nếu bạn google nó bạn tìm thấy ví dụ tốt. nhưng đối với độ cao, tôi có thể gửi dự án mẫu. –

+1

Vì vậy, đây là giải pháp cuối cùng và của bạn là gần nhất: Tôi đã quyết định viết chương trình vắt của riêng tôi. Các bước: 1, chương trình Extractor trích xuất các tệp từ tài nguyên 2, chương trình Extractor khởi chạy trình cập nhật chính bằng ShellExecuteEx 3, Khi trình cập nhật hoàn tất, chương trình trình trích xuất sẽ xóa các tệp khỏi thư mục temp. Điều này hóa ra lại là giải pháp tốt nhất thay vì sử dụng sự nhảm nhí của bên thứ 3. Cảm ơn! – Steve

12

Cá nhân tôi sẽ sử dụng Thiết lập Inno, vì nó rất phù hợp với loại tác vụ này. Xóa các tập tin là rất dễ dàng bằng cách sử dụng các sự kiện kịch bản, và thực hiện xóa của bạn như một phần của bước trình cài đặt bài đăng.

+0

Trên thực tế, thiết lập Inno được thiết kế để thực hiện chính xác những gì bạn đã mô tả trong câu hỏi của bạn. Chắc chắn, có những cách khác để làm những gì bạn hỏi. –

+1

+1. Có gì không thích về Inno? Nó được viết bằng Delphi, trong trường hợp giúp. Và nó chỉ là về mọi thứ bạn cần. Nếu có chức năng khác mà bạn không thể thực hiện với kịch bản lệnh (có thể làm LOTS), bạn có thể viết một DLL hoặc EXE và gọi nó cho các công cụ bổ sung. –

+0

1, tôi không muốn hiển thị bất kỳ hộp thoại Innosetup nào (Chào mừng bạn đến cài đặt, blah, blah) 2, Nếu chương trình hiển thị thông báo lỗi, bây giờ sẽ có hai nút thanh tác vụ, một bởi Inno và một bởi ứng dụng của tôi - gây nhầm lẫn cho người dùng. Đây là một không-đi. – Steve

0

Có lẽ không phải là một câu trả lời Delphi, nhưng nếu bạn mua một giấy phép cho WinRAR bạn có thể sử dụng chức năng thiết lập đơn giản sẵn có (bạn nén để SFX tập và kịch bản được lưu trữ trong một tập tin bình luận)

Rất dễ sử dụng , có thể làm sạch sau khi chính nó và nén độc đáo!