wince 自动启动程序设置
這是我在做wince6的時候為設置自啟動而尋找的方法。我發現公司定的這個設備在“Program Files”和windows文件夾下放置的東西在機子重啟之后就什么都沒有了。我只有使用注冊表測試,發現重啟后還存在,因此我用注冊表方式設置了自啟動。而在這個過程中,我發現如果程序放在SD卡內是不行的,只有放在nand才行。為什么放在SD卡內不可以自啟動,原因在我下面搜集的幾篇文章中找到了,原來SD卡是在自啟動程序之后才加載了驅動運行起來的。
?
?
?
wince?自動啟動程序設置
| 修改注冊表[HKEY_LOCAL_MACHINE\init] |
?
如何讓應用程序隨wince操作系統自啟動
????如何讓應用程序隨wince操作系統自啟動呢?我搜索了一下,網上有不少方法,但有時也會有疏漏的地方,通常一點小小的錯誤也會導致整個環節不能進行下去。在此,我想跟大家共同探討一下,歡迎大家指正。
首先,假設你的應用程序為:MyApp.exe。
方法一:主要思想:將應用程序及其快捷方式也添加到映像里,再將快捷方式添加到StartUp目錄下,這樣當系統運行后應用程序就能自動運行。
步驟:
1先保證原工程文件是可以編譯成功的。假設編譯好的nk.bin文件所在文件夾為xxx_Relase。
2創建快捷方式文件MyApp.lnk,文件內容如下:
10#”\Windows\MyApp.exe”(注意引號)
3在pb中修改project.bib文件,在FILES Section添加:
MyApp.exe ?? $(_FLATRELEASEDIR)\MyApp.exe NK H
MyApp.lnk ?? $(_FLATRELEASEDIR)\MyApp.lnk?? NK H
(注:$(_FLATRELEASEDIR)表示xxx_Relase文件夾;NK后面的H表明加入到nk.bin中的文件為隱藏屬性)
4?把快捷方式添加到StartUp目錄下,具體為:
修改工程的project.dat文件,添加如下內容:
Directory("\Windows\Startup"):-File("MyApp.lnk","\Windows\MyApp.lnk")
5從道理上講,如果這時把MyApp.exe和MyApp.lnk拷貝到xxx_Relase文件夾下,然后Build->MakeImag的話就會把你的應用程序添加到NK里,但實際情況并非如此,經我實驗,先要把工程文件全部rebuild一下,我這兒是sysgen了一下,如果你設置了在編譯完后MakeImage?的話,會有錯誤提示你未在你的磁盤上找到MyApp.exe。不用管它。把MyApp.exe和MyApp.lnk文件拷貝到xxx_Relase文件夾下,然后MakeImage一下(記住此時千萬不能再rebuild了,否則會前功盡棄),把生成的NK.bin燒寫到flash里,這樣就可以看到你的應用程序MyApp.exe自啟動了.
方法二:主要思想:將應用程序添加到映像里,然后用你的應用程序直接替換Wince的桌面程序。
步驟:
1.?像方法一一樣把你的應用程序添加到映象里。
????提示:要查看添加映象是否成功,可以在操作系統啟動后,看一下windows目錄下是否有你的應用程序MyApp.exe(先要設置為可以查看系統文件和隱藏文件)。
2.修改shell.reg(若在pb里找不到,可以到xxx_Relase文件夾下找):
[HKEY_LOCAL_MACHINE\init]
"Launch50"="explorer.exe"
"Depend50"=hex:14,00, 1e,00
把這個explorer.exe改成你的應用程序(比如:MyApp.exe)。
3. MakeImage一下(還是記住不能再build了),把生成的NK.bin燒寫到flash里,這樣就可以看到你的應用程序MyApp.exe自啟動了.
這樣做的好處是啟動的時候wince的桌面程序都不會啟動了,壞處是當你把應用程序關閉的時候由于原wince桌面程序的丟失而會使機器死機。
方法三:主要思想:將應用程序添加到映像里,然后修改注冊表,讓應用程序自啟動。這回不替換wince的桌面程序,而是讓wince像加載桌面一樣加載你的應用程序,效果跟方法一是一樣的。
步驟跟方法二是一樣的,只是第二步稍有不同:
在shell.reg文件中[HKEY_LOCAL_MACHINE\init]之下添加如下語句:
"Launch80"="MyApp.exe"
"Depend80"=hex:1E,00
說明:"Depend80"=hex:1E,00用來設置啟動順序和依賴程序,若你的應用程序不依賴于其它程序,這句可以不加。
另外,應用程序也不一定就要加載到映象文件里,可以直接從u盤,硬盤,sd卡等加載,但是要先保證你的應用程序自啟動時系統已能正確識別掛接的u盤,硬盤,sd卡等。
?
有兩個地方啟動程序: 1. 在注冊表HKLM\Init上加入鍵值:Launch99="你的程序名(可以是絕對路徑)",如果你的程序要依賴別的程序,還要加入:Depend99=依賴程序的啟動序號(可以看看Init下其它程序的啟動順序) 2.好像是在HKLM下有個WBT,里面有個地方也可以加入啟動程序,每次注銷都會重新啟動一遍,而Init只有在重新開機時才啟動。 你要啟動的程序,可以放在你的flash卡上(Init需要加入絕對路徑),或者加入bib文件,編譯進內核。?
??WinCE?應用程序開機自啟動方法
近日在開發過程中遇到WinCE應用程序開機自動運行的問題,在網上找了找,發現大概有以下三種方法:
?
1、?將應用程序和應用程序快捷方式添加到映像里,再將快捷方式添加到StartUp目錄下,這樣當系統運行后應用程序就能自動運行;
?
2、?直接替換Wince的SHELL,即修改注冊表:
?
[HKEY_LOCAL_MACHINE\init]
"Launch50"="explorer.exe"
"Depend50"=hex:14,00, 1e,00
?
把這個explorer.exe改成你的應用程序(比如:MyApp.exe);
?
3、?把應用程序加入到映像,修改注冊表:
[HKEY_LOCAL_MACHINE\init]
"Launch80"="MyApp.exe"
"Depend80"=hex:1E,00
?
可以設置啟動順序和依賴程序;
?
以上方法都可行,但是都存在一個問題,就是應用程序是集成到NK里面的,也就是說每次升級應用程序都要重新編譯下載內核,很麻煩,尤其在程序調試階段,大家都希望把應用程序放在SD卡上,這樣更新起來比較容易;據說通過第三種方法可以實現,即修改"Launch80"="MyApp.exe"為"Launch80"="\STDCard\MyApp.exe"( STDCard為SD卡目錄),但是我試了一下沒有成功,因為Launch80運行時SD卡的文件驅動還沒有加載,找不到MyApp.exe文件。同樣,采用快捷方式加載SD卡里的應用程序也不可行。
所以我采用了另一種方法,自己編了一個小程序,比如叫ShellExe.exe,將此程序加入到映像里,通過StartUp快捷方式調用ShellExe,ShellExe再去調用SD卡里的應用程序,具體實現步驟如下:
1、?在eVC下編譯如下代碼:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR????lpCmdLine,
int???????nCmdShow)
{
WIN32_FIND_DATA fd;
HANDLE hd=INVALID_HANDLE_VALUE;
int iCount = 20;
while(iCount--)
{
hd=::FindFirstFile(lpCmdLine,&fd);
Sleep(500);
if(INVALID_HANDLE_VALUE!=hd) break;
}
if(0==iCount) return 0;
FindClose(hd);
SHELLEXECUTEINFO ShExeInfo={0};
ShExeInfo.cbSize=sizeof(SHELLEXECUTEINFO);
ShExeInfo.fMask=SEE_MASK_NOCLOSEPROCESS;
ShExeInfo.hwnd=NULL;
ShExeInfo.lpVerb=NULL;
ShExeInfo.lpFile=lpCmdLine;
ShExeInfo.lpParameters=L"";
ShExeInfo.lpDirectory=NULL;
ShExeInfo.nShow=SW_SHOW;
ShExeInfo.hInstApp=NULL;
ShellExecuteEx(&ShExeInfo);
return 0;
}
生成ShellExe.exe的可執行文件,此段代碼主要功能是查找指定的應用程序,然后執行;下面這段代碼可以保證在SD卡文件系統正確加載后才去執行應用程序;
while(iCount--)
{
hd=::FindFirstFile(lpCmdLine,&fd);
Sleep(500);
if(INVALID_HANDLE_VALUE!=hd) break;
}
文件的名稱和路徑由命令行參數指定:
ShExeInfo.lpFile=lpCmdLine;2、?新建一個快捷方式,如Autorun.lnk,按如下方式編輯其內容:
?
21#\windows\shellexe.exe \stdcard\MyApp.exe其中\stdcard\MyApp.exe應用程序的絕對路徑;
?
3、?將MyApp.exe和Autorun.lnk添加到NK里,方法是在project.bib文件內加入如下內容:
?
ShellExe.exe f:\WINCE420\PBWORKSPACES\LioetEnTer\RelDir\ShellExe.exe NK S
Autorun.lnk f:\WINCE420\PBWORKSPACES\LioetEnTer\RelDir\Autorun.lnk NK S注意:ShellExe.exe的屬性不能帶H(隱藏).
?
4、?在project.dat里加入如下內容:
?
Directory("\Windows\Startup"):-File("Autorun.lnk","\Windows\Autorun.lnk")5、?選擇Make Image生成映像(當然Build也可以,就是慢點兒),燒到FLASH里,開機運行,可以看到SD卡里的MyApp.exe被正確執行。
?
總結
這種方法用起來比較方便,ShellExe.exe不用每次都重新編譯,只要根據應用程序路徑修改Autorun.lnk即可,可以加載Flash、U盤、SD卡里的應用程序。調試及升級應用程序就不用重新燒寫內核了。
?
WinCE自啟動Shell的問題
WinCE開機即運行定制的Shell是很多系統的基本要求,有時還需要屏蔽WinCE自帶的Shell。WinCE中程序的自啟動,一般有兩個實現方法,修改注冊表和添加自啟動快捷方式。修改注冊表比較方便,如下:
?
???????[HKEY_LOCAL_MACHINE\init]
?????????"Launch70"="MyApp.exe"
?????????"Depend70"=hex:14,00,1e,00
?
??????只要將MyApp.exe打包到NK,并在platform.reg中加入上面的注冊表信息,這樣WinCE啟動時便會自動運行該程序。但這時WinCE自帶的Shell總是先出來,然后才運行MyApp.exe,為了避免這種情況,我們可以將注冊表設置修改如下:
?
???????[HKEY_LOCAL_MACHINE\init]
?????????"Launch50"="MyApp.exe"
?????????"Depend50"=hex:14,00,1e,00
?
??????即將原來啟動explorer.exe的值換為MyApp.exe。這樣WinCE啟動時直接進入定制的Shell,而不啟動explorer.exe。但這時有可能引入了新問題,如果定制的Shell是基于MFC編寫的,并且其中用到了如CFileDialog等類庫時,就會出現意想不到的情況,如下圖所示:
?
上圖是在不啟動Explorer.exe時,嘗試導入注冊表文件出現的狀況截圖,而在啟動explorer.exe時是沒有問題的。這說明CFileDialog在某種程度上依賴于explorer.exe,具體細節沒研究。但說明不啟動explorer.exe,基于MFC的Shell運行時就可能會出問題。所以explorer.exe必須啟動,但又不能出現WinCE界面。要解決這個問題自然就想到修改explorer.exe了。WinCE5.0和WinCE6.0中,這一部分的代碼都是公開的,在WinCE6.0中Shell的相關代碼在C:\WINCE600\PUBLIC\SHELL\OAK\HPC\EXPLORER\MAIN目錄下。
?
???????大致看了一下這一部分的代碼,發現只需修改如下兩個文件,就應該能實現需求。
?
???????C:\WINCE600\PUBLIC\SHELL\OAK\HPC\EXPLORER\MAIN\desktop.cpp
?
+ expand sourceview plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
bool CDesktopWnd::Create()??
{??
?
????IShellFolder????*pSHF;??
????FOLDERSETTINGS fs;??
????RECT rc;??
????HRESULT hr = E_FAIL;??
??????
????// Get a shell folder for the desktop??
????hr = SHGetDesktopFolder(&pSHF);??
????if(hr || !pSHF)??
????????goto Cleanup;??
?
????// create a shell view for it??
????hr = pSHF->CreateViewObject(NULL, IID_IShellView, (LPVOID *)&_psv);??
????if(hr || !_psv)??
????????goto Cleanup;??
?
????fs.ViewMode = FVM_ICON;??
????fs.fFlags = FWF_DESKTOP | FWF_ALIGNLEFT | FWF_NOSCROLL;??
?
????//++changed by hjb??
????//將Desktop的窗口大小設為0??
????//SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));??
????SetRect(&rc, 0, 0, 0, 0);??
????????//--changed by hjb??
??????
????// create the desktop's view window (no need to AddRef since CreateViewWindow does it)??
????hr = _psv->CreateViewWindow(NULL,??&fs, (IShellBrowser *)this, &rc, &_hWnd);??
????if(hr || !_hWnd)??
????{??
????????Release();??
????????goto Cleanup;??
????}??
?
????RegisterDesktop(_hWnd);??
?
Cleanup:??
????if(pSHF)??
????????pSHF->Release();??
?
???return (hr == S_OK);??????
}?
bool CDesktopWnd::Create()
{
?
????IShellFolder????*pSHF;
????FOLDERSETTINGS fs;
????RECT rc;
????HRESULT hr = E_FAIL;
???
????// Get a shell folder for the desktop
????hr = SHGetDesktopFolder(&pSHF);
????if(hr || !pSHF)
????????goto Cleanup;
?
????// create a shell view for it
????hr = pSHF->CreateViewObject(NULL, IID_IShellView, (LPVOID *)&_psv);
????if(hr || !_psv)
????????goto Cleanup;
?
????fs.ViewMode = FVM_ICON;
????fs.fFlags = FWF_DESKTOP | FWF_ALIGNLEFT | FWF_NOSCROLL;
?
????//++changed by hjb
????//將Desktop的窗口大小設為0
????//SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));
????SetRect(&rc, 0, 0, 0, 0);
????????//--changed by hjb
???
????// create the desktop's view window (no need to AddRef since CreateViewWindow does it)
????hr = _psv->CreateViewWindow(NULL,??&fs, (IShellBrowser *)this, &rc, &_hWnd);
????if(hr || !_hWnd)
????{
????????Release();
????????goto Cleanup;
????}
?
????RegisterDesktop(_hWnd);
?
Cleanup:
????if(pSHF)
????????pSHF->Release();
?
???return (hr == S_OK);???
}
?
???????C:\WINCE600\PUBLIC\SHELL\OAK\HPC\EXPLORER\MAIN\explorer.cpp
?
+ expand sourceview plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
DWORD WINAPI CreateTaskBar(LPVOID pEvent)??
{??
????HANDLE hSyncEvent = *((HANDLE *) pEvent);??
????CTaskBar *pTaskBar = NULL;??
????HWND hwndTB = NULL;??
??????
????pTaskBar = new CTaskBar;??
??????
????//++added by hjb??
????//在創建任務欄時強制終止??
????if(pTaskBar)??
????{??
????????delete pTaskBar;??
????????SetEvent(hSyncEvent);??
????????return 0;??
????}??
????//--added by hjb??
???????
????if(!pTaskBar)??
????{??
????????SetEvent(hSyncEvent);??
????????return 0;??
????}??
?
????g_TaskBar = pTaskBar;??
????if(!pTaskBar->Register(g_hInstance))??
????{??
????????g_TaskBar = NULL;??
????????delete pTaskBar;??
????????SetEvent(hSyncEvent);??
????????return 0;??
????}??
?
????RegisterTaskBar(pTaskBar->GetWindow());??
????SetEvent(hSyncEvent);??
?
????DWORD dwRet = pTaskBar->MessageLoop();??
?
????delete pTaskBar;??
?
????return dwRet;??
}?
DWORD WINAPI CreateTaskBar(LPVOID pEvent)
{
????HANDLE hSyncEvent = *((HANDLE *) pEvent);
????CTaskBar *pTaskBar = NULL;
????HWND hwndTB = NULL;
???
????pTaskBar = new CTaskBar;
???
????//++added by hjb
????//在創建任務欄時強制終止
????if(pTaskBar)
????{
????????delete pTaskBar;
????????SetEvent(hSyncEvent);
????????return 0;
????}
????//--added by hjb
???
????if(!pTaskBar)
????{
????????SetEvent(hSyncEvent);
????????return 0;
????}
?
????g_TaskBar = pTaskBar;
????if(!pTaskBar->Register(g_hInstance))
????{
????????g_TaskBar = NULL;
????????delete pTaskBar;
????????SetEvent(hSyncEvent);
????????return 0;
????}
?
????RegisterTaskBar(pTaskBar->GetWindow());
????SetEvent(hSyncEvent);
?
????DWORD dwRet = pTaskBar->MessageLoop();
?
????delete pTaskBar;
?
????return dwRet;
}
?
修改完這兩處后,先編譯該目錄,然后再重新編譯整個系統(執行Sysgen)應該就可以了。Explorer.exe依然啟動,依然可以聽到WinCE啟動的聲音,但WinCE的界面已經屏蔽掉了。此時,基于MFC的Shell也能正常工作,如下圖所示:?
?
?
??????在實際操作時,我沒有通過修改源代碼編譯來完成這個測試。因為在編譯C:\WINCE600\PUBLIC\SHELL\OAK\HPC\EXPLORER\MAIN目錄時,發現它只生成了explorer.lib。考慮到重新編譯整個系統的時間太長,所以直接修改了工程目錄下的explorer.exe的文件,MakeImg后測試的。這里應該有快速編譯的方法,但目前不知怎么弄。
?
??????修改后,在WinCE6.0的模擬器中測試,達到了預想的效果。這樣就大概解決了基于MFC的Shell和Explorer.exe之間的矛盾,是不是有隱患還不清楚,目前看來沒問題。
?
另外需要注意,修改public和private目錄下的文件時,一定先做好備份,以免后患。??????????
??????修改后的WinCE6.0的explorer.exe及演示視頻的下載地址:
?
???????http://files.cnblogs.com/we-hjb/WinCE_Shell.rar
?
引用網址:http://www.cnblogs.com/we-hjb/archive/2008/12/28/1364070.html
?
?
HKEY_LOCAL_MACHINE\init\Launch80="\nandflash\em9161_xwj.exe"
?
[PB操作使用技巧]WinCE下直接啟動應用程序的方法
其實讓一個程序在wince里啟動和windows里差不多,直接設置其為啟動項,這個有幾個方法。一個就是制作一個快捷方式,指向我們的應用程序如app.exe,然后將快捷方式放到\windows\startup下面。
????步驟如下:(假設app.exe已經拷貝到windows下面)
????1?在pb中創建一個文件,文件類型選txt,然后命名為.lnk后綴,假設名字為test.lnk
????2?編輯其內容為: 16#\windows\app.exe。備注:前面的16是#?后面所有字符的總和,包括空格。Wince的幫助文檔上說這么定義就行,但是我嘗試后,最后down到目標機上面時提示找不到文件,在wince里查看這么創建的test.lnk的屬性,發現其指向\windows\app.exe后面還有兩個方框,因此不對,我的解決方法是修改test.lnk的內容為16#"\Windows\app.exe"
????3?編輯好lnk文件內容后在pb中修改project.bib。在files段后面添加下面一行:(和添加別的文件到image中類似,見我的《WinCE中如何向image中添加文件》,也要在pb的flatform菜單的setting下添加build語句,不再贅述)
????????test.lnk $(_FLATRELEASEDIR)\test.lnk NK S
????在project.dat中增加下面一行:
?????????Directory("\Windows\startup"):-File("test.lnk","\Windows\test.lnk")
????這樣后系統啟動后就會自動啟動我們的程序了。
???
????另外一種方法是編輯注冊表:在project.reg中添加如下內容
????????[HKEY_LOCAL_MACHINE\init]
????????"Launch80"="app.exe"
????????"Depend80"=hex:14,00,1e,00
????這個是設定啟動順序,launch后面的數字越大的越是后啟動,Depend80后面的指定依賴項,為16進制,上面的語句表明依賴項為launch20定義的device.exe和launch30中定義的gwes.exe,?注意Launch后面的數字范圍為0到99?,此范圍之外的將不會有效果。
????這樣兩種方法的效果都是系統都是系統先啟動資源管理器explorer.exe(就是看到的默認桌面),然后啟動我們的程序,(如果利用taskman shell然后去掉任務欄那么效果更好)但是這樣還不夠,我們如何不顯示桌面,直接顯示我們的程序呢?
????網上有人介紹的方法是去掉standard shell,但是我編譯總是報錯。我采用的方法是替換注冊表中lauch50中的explorer.exe為我的app.exe,即搞定。
????修改注冊表的方法:先把帶KITL的系統跑起來,在PB的TOOLS->Remote registry editor里修改,驗證有效后,再去修改platfrom.reg,?或者自己寫個REG文件,然后在platform.reg里INCLUDE進來SYSGEN后確認PBWORKSPACE里相關項目的REL目錄里reginit.ini文件里包含了自己做的修改后make image然后DOWNLOAD下去就OK了。
????值得補充的是,我們前面介紹的步驟中那個修改平臺setting,添加語句的,是因為我每次都是重新sysgen和build,如果只是簡單的make image的話(都是pb中的build OS菜單下的命令),那么將直接用release中的內容,因此也可以直接將文件放到release文件夾,然后改project.bib等實現往image中添加文件。?同樣,也可以直接修改release中的shell.reg中的launch50值為我們自己的程序(或者類似修改reginit.ini文件,reginit.ini文件存放有所有wince的靜態注冊表,來達到去掉桌面,直接啟動我們程序的效果)。
注意,這么啟動的程序,如果點擊關閉,就會死機的,因為沒有窗口運行了。實際運用中,當然不會讓用戶關閉我們的程序,除非他一起關閉系統。
如果也需要build的話,可以通過往image中添加文件的方法將我們改好的shell.reg添加到release目錄
總結
以上是生活随笔為你收集整理的wince 自动启动程序设置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinCE 控制面板的创建
- 下一篇: WinCE OAL中的OEMIoCont