2011-01-21 14 views
6

Farklı bileşenlere sahip bir C++ projesi üzerinde çalışıyorum. Uygulamayı bir windows servisi olarak başlatmamız gerekiyor. Proje yönetilmeyen C++ kodudur. Ben bir C# windows hizmeti ve farklı bileşenleri başlatmak için bir işlevi olacak bir C-stili dll yazdım ve onları durdurmak için başka bir. Ben şu var pencereler hizmetin ServiceBase alt sınıfındaC# windows hizmetinden C++ dll (yönetilmeyen kod) çağırma (yönetilen kodda yazılmış)

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 iki dosya, bir başlık ve bir .cpp vardır :

[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()); 
    } 
} 

Ayrıca ben OnStart içinde benzer ana iç kodu ile bir konsol testi uygulaması vardır. SetUnhandledException işlevi yorumlandığında, hem uygulama hem de windows hizmeti sorunsuz çalışır. Ben bu işlevi yorumsuz Fakat pencereler konsol uygulaması Tamam çalışır, ancak Windows hizmet aşağıdaki istisna verir:

System.DllNotFoundException: DLL 'RTSSd.dll' yüklenemiyor: belirtilen modül bulunamadı . (HRESULT özel durum: 0x8007007E) RTSWS.RTSWinService.runRTS (dize hizmet adı) RTSWS.RTSWinService.OnStart (dize [] args) D: \ work \ project \ ... \ RTSWinService.cs: satır 39

Windows forumlarının C: \ WINDOWS \ System32 dosyasında başlattığı farklı forumlarda bazı threadlarda okudum ve bir DirectoryInfo başlatıldığından ve tam adının yazdırılmasından bu yana doğrudur. Varsayılan başlatma dizini Environment.CurrentDirectory = "windows hizmetinin çalıştırılabilir ve dll olduğu dizin" ile değiştirmeyi denedim, ancak bu çalışmadı. İşlem dizini değiştirmeyi de denedim, ancak bu da başarısız oldu. Diğer konular bu sonuca yol açıyor link text, ama gerçekten bu mu? Daha basit bir şey olabilir mi? SetUnhandledException işlevinin C++ değil C olarak yazıldığını ve benim aramam gereken başka birçok işlev olduğunu not etmeliyim. Gerekli tüm donanımlar, hizmet yürütülebilir dosyasının yanına yerleştirilir. Değerlendirmeleriniz bizim için çok kıymetlidir.

Teşekkürler.

+0

Sanity check: bağımlılık yürüteçünü açın, DLL dosyanızın bağımlı olduğu öğeye bakın, gerek DLL dosyanızın gerek bağlı DLL'lerinin yol üstünde bir yerde olduğundan emin olun. – Shog9

+0

Ayrıca, hizmetinizin yüklenmeye çalıştığı DLL'leri izlemek için SysInternal'ın filemonunu çalıştırabilirsiniz. Bir windows servisinin farklı bir kullanıcı oturumunda (ve masaüstünde) çalıştığını ve böylece kendi ortamının olduğunu unutmayın. Ve 'd:' (veya nereye yüklediğinizi) gerçekte gerçek bir yerel yol olduğundan emin olun, ne de SUBST'ed (orada yapıldı ;-) ;-) –

+0

Bağımlılık denetimi yaptı, ancak konsol uygulaması Sorun yok, eksik bağımlılıkların olmadığını varsayalım. Btw, hizmet alt yüklenemedi yükleme sorunu içine koştum ve onu kaldırmak için bir acı oldu :) – vnammour

cevap

2

Konsolda bir şey çalışıyor ancak hizmet olarak değilken, erişim izinlerinden şüpheleniyorum. Hizmetin kullanıcı olarak çalıştığından, d: \ work \ projects \ bin dosyasına okuma/yürütme erişimi olduğundan emin olun.

Diğer öneride, DLL'lerin geçerli dizini kullanmaktan daha uzak olduğu söylenecek daha doğrudan bir yol olan SetDllDirectory adlı öğeyi aramaktır. Pinvoke dll arama yoluna bakın this SO thread

Sistemin denemesini ve DLL'inizin bulunmasını izlemek için SysInternal's ProcMon'u da kullanabilirsiniz. Bazen DLL değil, DLL bir DLL dosyası bu sorunu vardır ve ProcMon bu sorunları bulmak için iyidir.

+0

Cevap ve yorumlar için çok teşekkürler. Ben hızlı oldu sevindim :) – vnammour

+0

Hizmet yerel bir hizmet olarak çalıştırıyorum. Ayrıca kullanıcı olarak denedim (& hesabım bu makinede bir yönetici) ve yerel sistem, ama farklı değildi. Ayrıca, OnStart yönteminin içinden SetDllDirectory ("D: \ work \ projects \ bin") çağrısı yaptık ve doğru döndü, ancak sorunu çözmedi. Bağımlılık aracını (depends.exe) açıp RTSSd.dll dosyasını incelediğimde, IESHIMS.DLL ve WER.DLL (sistem dlls belki) bulma konusunda bir hata verir. Ancak eksik bağımlılıklar varsa konsol uygulamasının başarısız olacağını varsayabilirim. – vnammour

+0

Programın nasıl kullanıldığını öğrenmeye değer, bu yüzden açık olan şeyler probleminizi çözmüyorsa, yanlış olanı çözmeye çalışıyor olabilirsiniz. Procmon çoğu zaman bunun ne olduğunu görmeye yardımcı olur. ProcMon'u önermek için –

1

Sadece bu ileti dizisini güncellemek istedim. Sorun, makinem için özel olduğunu ortaya çıkardı. Aynı codeet farklı bir makinede bir çekicilik gibi çalıştı, aynı windows versiyonu (Windows XP 32 bit, SP2). Her iki makinede de, Visual Studio 2008 hizmeti oluşturmak için kullanıldı. Tüm yorumlar ve cevap için çok teşekkürler. Bunu takdir ediyorum.

İlgili konular