差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

windowsbatch:sysnative [2013/06/10 15:17]
tony 建立
windowsbatch:sysnative [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​WindowsBatch}} 
-====== 找不到的msg.exe - 神奇的sysnative ====== 
-===== Problem ===== 
-某天遇到windows command - msg.exe在win7/​win8找不到的問題。這問題乍看之下非常的神奇,兩套不同的軟體但一個能夠使用一個則不行。在不行的那個軟體中加入Debug訊息,卻出現msg.exe找不道的怪異現象。這兩套軟體除了一個是C++做的一個是Java做的外,另外一個特點是32-bit與64-bit的Service之差別。Command都一樣為什麼32-bit的卻不能用呢?​ 
-===== Root Cause ===== 
-首先我透過了32與64位元的cmd.exe去執行msg.exe:​ (system32 for 32-bit;syswow64 for 64-bit)\\ 
-{{:​windowsbatch:​execute_msg_in_diff_cmd.png|}}\\ 
-可以發現在32位元的情況下根本找不到msg.exe,接著到C:/​windows下搜尋msg.exe,確認system32與syswow64中是否都有msg.exe。事實是:​ 僅system32中有msg.exe。\\ 
-{{:​windowsbatch:​search_msg_win7.png|}}\\ 
-這是系統限制,issue可以不解嗎?​ 但問題是另外一個軟體做的到阿! 把一個軟體從32變成64位元是較難些,還是看看要如何用較簡單的方式去解決這個問題吧! 
-===== How to ? ===== 
-我試過**直接呼叫%windir%\system32\msg.exe**,也確認過**%PATH%有指到system32**,但事實上32-bit的service是無法直接存取system32的。還好這時候看到個一個叫**sysnative**的東西,它可以透過這個資料夾讓32的應用程式可以訪問到system32中的東西。\\ 
-==== Batch ==== 
-可以根據執行一次msg.exe去確認exit code,若非0代表有問題則改用sysnative的msg.exe:​ 
-<code bash> 
-@echo off 
-set CMD=msg.exe 
  
-where %CMD% >NUL 2>&1 
- 
-if not %errorlevel% == 0 ( 
- set CMD=%windir%\sysnative\msg.exe 
-) 
- 
-%CMD% 
-</​code>​ 
-\\ 
-也可以透過判斷sysnative中的msg.exe是否存在去決定要執行的Command:​ 
-<code bash> 
-@echo off 
-if exist "​%windir%\sysnative\msg.exe"​ (  
- set CMD="​%windir%\sysnative\msg.exe" ​ 
-) else ( 
- set CMD=msg 
-) 
- 
-%CMD% 
-</​code>​ 
-==== C/C++ ==== 
-我寫了一個intMsgCommand的function,接收結果cmd與要發出的message參數。首先透過執行一次msg去確認exit code為0,如果不為0就用sysnative做法。這裡需注意的是:​ 如果採用batch中第二個做法是行不通的,因為在程式中判斷sysnative是否存在會得到false的結果。最後會把要執行的command給串到cmd參數中。 
-<code cpp> 
-void intMsgCommand(char* cmd, char *message){ 
- int ret = system("​msg"​);​ 
- if( ret == 0 ){ 
- sprintf(cmd,​ "msg * %s", message); // default command 
- return; 
- 
-  
- const int size = GetWindowsDirectory(NULL,​ 0); 
- char* windir = new char[size]; 
- 
- if( GetWindowsDirectory(windir,​ size) != 0){ 
- char msgcmd_path[50];​ 
- sprintf(msgcmd_path,​ "​%s\\sysnative\\msg.exe",​ windir); 
- sprintf(cmd,​ "%s * %s", msgcmd_path,​ message); ​ 
- 
- delete windir; 
-} 
-</​code>​ 
-\\ 
-=====    ===== 
-友藏內心獨白:​ 這問題其實有點鳥。 
-===== Reference ===== 
-  * [[http://​leonax.net/​p/​2601/​magic-of-sysnative-folder/​|神奇的SysNative文件夹]] 
-  * [[http://​msdn.microsoft.com/​en-us/​library/​windows/​desktop/​aa384187(v=vs.85).aspx|MSDN - File System Redirector]] 
- 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~