比如自動安裝qq2013,給段代碼吧,聽說要用到等待函式。
uj5u.com熱心網友回復:
如果是靜默安裝的話要搞清楚安裝程式注冊了什么dll,改了什么鍵值,釋放了什么檔案,自己寫代碼代替就行了。uj5u.com熱心網友回復:
一般安裝的時候點詳細資訊就可以看到這些資料。uj5u.com熱心網友回復:
給一段DELPHI的代碼吧uj5u.com熱心網友回復:
思路: 1、創建一個虛擬桌面2、撰寫一個自動打開安裝程式、并且下一步 下一步 完成的程式。根據句柄來操作點擊
3、在虛擬桌面中運行2步驟撰寫的程式
范例看下面代碼,備注下面代碼不是我寫的了。我自己實作過自動安裝。
OpenDesktop//獲取桌面句柄
SwitchDesktop//激活/轉到指定的桌面
globaladdatom//創建全域原子
globalfindatom//查找全域原子
globaldeleteatom//洗掉全域原子
getasynckeystate//判斷虛擬鍵的狀態
CreateProcess//打開指定的行程
GetCurrentThreadId//獲取當前ID
GetThreadDesktop//獲取當前桌面句柄
好了就這些,下面我說下流程
剛看網上的資料的時候,感覺好像只要CreateDesktop來創建桌面再用SwitchDesktop來轉到指定桌面即可,然而事情卻沒這么簡單.創建虛擬桌面后,我將SwitchDesktop函式輸入行程式的按鈕事件里,我一按按鈕,令我痛哭流涕的事情發生了------轉到的桌面干干凈凈什么都沒有,沒有桌面圖示沒有任務欄甚至打不開任務管理器,沒辦法,含淚按下電腦的重啟按鈕(好幾千呢555).
我繼續在網上查找資料,發現要在新創建的桌面顯示圖示,必須先在新創建的桌面打開桌面行程explorer.exe(一般情問下我們結束掉這個行程桌面就會消失就是這個道理),現在就用到了CreateProcess函式,CreateProcess函式如何能在其它桌面創建行程呢?CreateProcess有個TStartupInfo結構的引數,該結構中有個叫lpDesktop的成員,它指定了在哪個桌面創建行程(不對其賦值則為當前桌面),請看代碼:
var sin:TStartupInfo;s:string;
sin.cb:=sizeof(sin);
sin.wShowWindow:=SW_SHOW;
sin.dwFlags:=STARTF_USESHOWWINDOW;
s:='a';
sin.lpDesktop:=pchar(s);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
其中的字符a為創建桌面的名稱,該名稱在創建桌面的函式中指定.
接下來的問題是轉到新的桌面之后,運行的自身程式就不見了,怎樣才能轉回原來的桌面呢?我用了一個愚蠢的辦法,在創建新桌面和新桌面行程的同時在新桌面上將本程式再次打開,這樣實際上創建了幾個新桌面自身程式就運行了幾個實體,看代碼:
CreateProcess(pchar(extractfilepath(application.ExeName)+'這里是程式的名字'),nil,nil,nil,False,0,nil,nil,sin,pin);
將這行代碼放到創建桌面行程代碼的后面,這個問題就解決了,一波未平一波又起新了問題又產生了,而且還是兩個很嚴重的問題:
1。我創建桌面的代碼是寫在表單載入的程序中的,這就意味著每創建一個自身實體就多了N個虛擬桌面。
2。新創建的實體行程并不能保存有第一個實體行程的句柄,這樣就無法對桌面進行操作。
對于第一個問題我是用全域原子法來解決的,在程式啟動時先使用globalfindatom查找全域原子,若不薦在則表示未運行過實體行程,那么就創建一個全域原子并創建虛擬桌面,若存在,而不創建虛擬桌面,但還是要創建一個全域原子(原因不用我說了吧~),在表單的退出代碼中別忘了 globaldeleteatom掉創建的全域原子。
對于第二個問題,即然無法繼承就自已查找句柄吧;前面說過在創建虛擬桌面時會為創建的桌面指定一個名稱,現在這個名稱的作用體現出來了,OpenDesktop函式其中一個引數為桌面的名稱,該函式的回傳值就是桌面的句柄。新創建的虛擬桌面可以用這個方法獲得句柄,但是默認桌面怎么獲取呢?這個更簡單,因為默認的桌面名稱就是“default”,只要把這個字符放入OpenDesktop函式中便能輕松獲取默認桌面的句柄。在句柄得到了,只要使用SwitchDesktop(引數就是桌面句柄)函式就能轉到指定桌面了。
PS:默認桌面的名稱我開始也不知道,但我無意中在網上發現一個函式:getuserobjectinformation,這個函式可以根據桌面的句柄獲取桌面的名稱,當前桌面的句柄可以用GetThreadDesktop和GetCurrentThreadId()獲取,GetCurrentThreadId()的功能是獲得當前ID,這個ID作為GetThreadDesktop的引數用來獲取當前桌面句柄。這樣就得到了桌面的名稱
不多說了附上我的源代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
Timer1: TTimer;
Timer2: TTimer;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
h1:thandle;
h2:thandle;
h3:thandle;
h4:thandle;
h5:thandle;
h6:thandle;
si:TStartupInfo;
sin:TStartupInfo;
pin:TProcessInformation;
s:string;
desk:thandle;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); //創建桌面
begin
timer1.Interval:=50;
timer2.Interval:=1000;
sin.cb:=sizeof(sin);
sin.wShowWindow:=SW_SHOW;
sin.dwFlags:=STARTF_USESHOWWINDOW;
if globalfindatom('mfk')=0 then
begin
globaladdatom('mfk');
h1:=GetThreadDesktop(GetCurrentThreadId());
s:='a';
sin.lpDesktop:=pchar(s);
h2:=CreateDesktop(pchar(s),nil,nil,DF_ALLOWOTHERACCOUNTHOOK,GENERIC_ALL,nil);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
CreateProcess(pchar(extractfilepath(application.ExeName)+'雙開工具.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
s:='b';
sin.lpDesktop:=pchar(s);
h3:=CreateDesktop('b',nil,nil,0,MAXIMUM_ALLOWED,nil);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
CreateProcess(pchar(extractfilepath(application.ExeName)+'雙開工具.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
s:='c';
sin.lpDesktop:=pchar(s);
h4:=CreateDesktop('c',nil,nil,0,MAXIMUM_ALLOWED,nil);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
CreateProcess(pchar(extractfilepath(application.ExeName)+'雙開工具.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
s:='d';
sin.lpDesktop:=pchar(s);
h5:=CreateDesktop('d',nil,nil,0,MAXIMUM_ALLOWED,nil);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
CreateProcess(pchar(extractfilepath(application.ExeName)+'雙開工具.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
s:='e';
sin.lpDesktop:=pchar(s);
h6:=CreateDesktop('e',nil,nil,0,MAXIMUM_ALLOWED,nil);
CreateProcess('c:\WINDOWS\explorer.exe',nil,nil,nil,False,0,nil,nil,sin,pin);
CreateProcess(pchar(extractfilepath(application.ExeName)+'雙開工具.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
end
else
begin
globaladdatom('mfk');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);//切換至桌面1
begin
desk:=OpenDesktop('default',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Button2Click(Sender: TObject); //切換至桌面2
begin
desk:=OpenDesktop('a',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Button4Click(Sender: TObject); //切換至桌面3
begin
desk:=OpenDesktop('b',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Button5Click(Sender: TObject); //切換至桌面4
begin
desk:=OpenDesktop('c',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Button6Click(Sender: TObject); //切換至桌面5
begin
desk:=OpenDesktop('d',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Button7Click(Sender: TObject); //切換至桌面6
begin
desk:=OpenDesktop('e',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(112)<>0) then
begin
desk:=OpenDesktop('default',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(113)<>0) then
begin
desk:=OpenDesktop('a',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(114)<>0) then
begin
desk:=OpenDesktop('b',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(115)<>0) then
begin
desk:=OpenDesktop('c',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(116)<>0) then
begin
desk:=OpenDesktop('d',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end;
if (getasynckeystate(VK_Control)<>0) and (getasynckeystate(117)<>0) then
begin
desk:=OpenDesktop('e',DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED);
SwitchDesktop(desk);
end
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
globaldeleteatom(globalfindatom('mfk'));
end;
uj5u.com熱心網友回復:
inno setup轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/120067.html
標籤:VCL組件開發及應用
