2011-02-11 19 views
4

質問:私はインストーラを持っており、プログラムと共にいくつかのネイティブdllをインストールします。 dllは別のフォルダにあり、これをパス環境変数に追加しました。SendMessageTimeoutが環境変数を更新しないのはなぜですか?

これは正常に実行され、Windowsシステムの設定を確認すると変数がパスに表示されます。

私は、コマンドラインプログラム/サービスを開始する場合は、それはDLLが見つからないです...

私はsetコマンドで環境変数のパスをチェックして、私のフォルダが存在していないと言います。

私は

SET path = %path%;my/folder/here/ 

を行い、その後、私のプログラムを起動した場合、それは動作します。

this MS KB articleによると、これはコンピュータを再起動する必要があるためです。

私は今

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);    

を行う場合を除き、私は以下のコードを使用してだけ、ということでしたが、エラーメッセージが消えません。 %path%のフォルダが正しく綴られていることを確認しました。

私は間違っていますか?

' http://www.pinvoke.net/default.aspx/Enums/SendMessageTimeoutFlags.html ' 
<Flags()> _ 
Public Enum SendMessageTimeoutFlags 
    SMTO_NORMAL = 0 
    SMTO_BLOCK = 1 
    SMTO_ABORTIFHUNG = 2 
    SMTO_NOTIMEOUTIFNOTHUNG = 8 
End Enum  

' http://ghouston.blogspot.com/2005/08/how-to-create-and-change-environment.html ' 
Public Const HWND_BROADCAST As Integer = &HFFFF 
Public Const WM_SETTINGCHANGE As Integer = &H1A  

' http://pinvoke.net/default.aspx/user32.SendMessageTimeout ' 
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _ 
Public Shared Function SendMessageTimeout(ByVal windowHandle As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal flags As SendMessageTimeoutFlags, ByVal timeout As Integer, ByRef result As IntPtr) As IntPtr 
End Function  

' http://support.microsoft.com/?kbid=104011 ' 
' http://blog.jtbworld.com/2005/11/set-environment-variable-using-vbnet.html ' 
Sub UpdatePath() 
    Dim result As Integer 
    ' SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,(LPARAM) "Environment", SMTO_ABORTIFHUNG,5000, &dwReturnValue); ' 

    ' CType("Environment", System.IntPtr) ' 
    Dim s As String = New String("Environment") 
    Dim ptr As IntPtr = Runtime.InteropServices.Marshal.StringToHGlobalUni(s) 

    'SendMessageTimeout(CType(HWND_BROADCAST, System.IntPtr), WM_SETTINGCHANGE, 0, ptr, SendMessageTimeoutFlags.SMTO_BLOCK Or SendMessageTimeoutFlags.SMTO_ABORTIFHUNG Or SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG, 5000, result) ' 
    SendMessageTimeout(CType(HWND_BROADCAST, System.IntPtr), WM_SETTINGCHANGE, 0, ptr, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, result) 
End Sub 

答えて

11

私はそれがUnicode/ANSI処理と関係があると思われます。基本システムはANSIでは "環境"を望んでいるようですが、シェルを含むほとんどのアプリケーションはUnicodeを望んでいます。うまく仕事を取得します

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 1000, NULL); 
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) L"Environment", SMTO_ABORTIFHUNG, 1000, NULL); 

:Cで、私は同じようにそれを送ります。 VB.Netで

私はあなたのようになりために同等と仮定します(。そして、あなたは、アンマネージコードを使用するつもりなら、あなたのメモリを解放することを忘れないでください)

Dim s As String = New String("Environment") 
Dim ptrA As IntPtr = Runtime.InteropServices.Marshal.StringToHGlobalAnsi(s) 
Dim ptrU As IntPtr = Runtime.InteropServices.Marshal.StringToHGlobalUni(s) 
SendMessageTimeout(CType(HWND_BROADCAST, System.IntPtr), WM_SETTINGCHANGE, 0, ptrA, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, result) 
SendMessageTimeout(CType(HWND_BROADCAST, System.IntPtr), WM_SETTINGCHANGE, 0, ptrU, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, result) 

+0

この回答完全に間違っています。なぜ人々は間違った答えをupvoteするのですか? Windowsは、使用しているAPIに応じて、Windowsメッセージのすべての文字列を自動的に変換します。 SendMessageTimeoutA()を使用する場合、ANSI文字列を送信する必要があります。 SendMessageTimeoutW()を使用するときは、ワイド文字列を送信する必要があります。そして、メッセージを受け取るウィンドウプロシージャは、常に正しい形式の文字列を受け取ります。 Unicode用にコンパイルされたアプリケーションでは、SendMessageTimeoutA()からANSI文字列として送信されたとしても、文字列はワイド文字として返されます。およびその逆。 – Elmue

関連する問題