2011-01-21 10 views
6

私はさまざまなコンポーネントを持つC++プロジェクトを開発中です。アプリケーションをWindowsサービスとして起動する必要があります。このプロジェクトはアンマネージドC++コードです。私はC#のWindowsサービスと、さまざまなコンポーネントを起動する機能を持つCスタイルのDLLと、それらを停止する別のものを書きました。 、私は次のようしているWindowsサービスのServiceBaseのサブクラスでC#Windowsサービス(マネージコードで書かれている)からC++ dll(アンマネージドコード)を呼び出す

using namespace PFDS; 
/* ... includes and declarations */ 
extern "C" __declspec(dllexport) int runRTS(char* service_name) 
{ 
    g_reserved_memory = (char*) malloc(sizeof(char) * RESERVED_MEMORY_SIZE); 
    _set_new_handler(memory_depletion_handler); 
    // this function is from a C++ .lib which is included in 
    // the linker input for the RTSS dll project setting. 
    // SetUnhandledExceptionHandler("RTS");  
    return 0; 
} 

: RTSS.h:

namespace PFDS 
{ 
    extern "C" __declspec(dllexport) int runRTS(char*); 
} 

RTSS.cpp dllが2つのファイルヘッダと.cppファイルを持っています:

[DllImport("RTSSd.dll")] 
public static extern int runRTS(string serviceName); 

protected override void OnStart(string[] args) 
{ 
    try 
    { 
    // the bin directory has all dependencies (dlls needed) 
    Environment.CurrentDirectory = "D:/work/projects/bin"; 
    eventLog1.WriteEntry("RTSWinService: Starting " + this.ServiceName); 
    int result = runRTS(this.ServiceName); 
    eventLog1.WriteEntry("Result of invoking runRTS = " + result); 
    } 
    catch (Exception e) 
    { 
    eventLog1.WriteEntry("Exception caught: " + e.ToString()); 
    } 
} 

さらに、OnStart内のコードと似たメインコードのコンソールテストアプリケーションがあります。 SetUnhandledException関数がコメントされると、アプリケーションとWindowsサービスの両方が問題なく実行されます。私はその関数のコメントを解除する場合でも、Windowsコンソールアプリケーションは、[OK]を実行しますが、Windowsサービスは、次の例外を出力します

System.DllNotFoundException:DLL「RTSSd.dll」を読み込むことができません:指定されたモジュールが見つかりませんでした。 RTSWS.RTSWinService.runRTS(文字列serviceName)の (RTSWS.RTSWinService.OnStart(String [] args)D:\ work \ project \ ... \ RTSWinService.csの行39

で例外が発生しました(HRESULTからの例外:0x8007007E)

私は、WindowsサービスがC:\ WINDOWS \ System32で開始するという別のフォーラムのスレッドを読みました.DirectoryInfoを初期化してそのフルネームを表示して以来、それは当てはまります。私はEnvironment.CurrentDirectory = "Windowsサービスの実行可能ファイルとDLLのディレクトリ"でデフォルトの開始ディレクトリを変更しようとしましたが、動作しませんでした。また、Processディレクトリを変更しようとしましたが、それも失敗しました。他のスレッドはこの結論につながりますlink text、それは本当ですか?何か簡単なことができますか? SetUnhandledException関数はCではなくC++で書かれているので、私が呼び出す必要がある他の多くの関数もあります。必要なDLLはすべてサービス実行可能ファイルの隣に置かれます。あなたのご意見は大変ありがとうございます。

ありがとうございました。

+0

健全性チェック:依存関係ウォーカーを開いて、DLLが依存しているものを確認し、依存するDLLとDLLの両方がパス上にあることを確認します。 – Shog9

+0

また、SysInternalのfilemonを実行して、サービスがロードしようとしているDLLを監視することもできます。 Windowsサービスは異なるユーザーセッション(およびデスクトップ)で実行されるため、独自の環境もあります。あなたの 'd:'(またはどこにインストールしても)実際にはネットワークでもSUBSTでもない実際のローカルパスであることを確認してください(;-) –

+0

依存関係のチェックは行いましたが、コンソールアプリケーションはいいえ問題は、私は、欠けている依存関係がないと仮定します。ところで、私はsubst'edドライブにサービスをインストールするという問題に遭遇しました。それを削除するのは苦痛でした:) – vnammour

答えて

2

コンソールでは動作しますが、サービスとして動作しない場合は、私はアクセス許可を疑います。 d:\ work \ projects \ binへの読み取り/実行アクセス権を持つユーザーとして、サービスが実行されていることを確認します。

もう1つの提案は、SetDllDirectoryを呼び出すことです。これは、DLLが現在のディレクトリを使用する場所よりも直接的な方法です。 pinvoke dll検索パスのthis SO threadを参照

SysInternal's ProcMonを使用してシステムを監視してDLLを見つけることもできます。時にはそれがDLLではないが、DLLが依存しているDLLに問題があり、ProcMonはこれらの問題を見つけるのに適している。

+0

答えとコメントに感謝します。私は速かったのでうれしいです:) – vnammour

+0

私はローカルサービスとしてサービスを実行しています。私もユーザー(&私のアカウントはこのマシンの管理者)とローカルシステムとして試してみましたが、違いはありませんでした。私はまた、OnStartメソッド内からSetDllDirectory( "D:\ work \ projects \ bin")を呼び出して、trueを返しましたが、問題を解決しませんでした。依存ツール(depends.exe)を開いてRTSSd.dllを調べると、IESHIMS.DLLとWER.DLL(おそらくシステムDLL)が見つからないというエラーが表示されます。しかし、私は、コンソールアプリケーションが、不足している依存関係があれば失敗したと仮定します。 – vnammour

+0

procmonの使い方を学ぶ価値はあるので、明白なことがあなたの問題を解決するわけではないので、あなたは間違った問題を解決しようとしているかもしれません。 Procmonはそれが何であるかを見るのに役立ちます。 –

1

このスレッドを更新したいだけです。 問題は私のマシンに限られていることが判明しました。同じコードセットは、別のマシン、同じWindowsバージョン(Windows XP 32ビット、SP2)で魅力的に機能しました。両方のマシンでVisual Studio 2008を使用してサービスを構築しました。 すべてのコメントと回答に感謝します。それは有り難いです。

関連する問題