2010-06-08 14 views
7

geçici olarak DLL arama yollarına bir dizin eklemek istediğiniz geçici bir dizin ekleme - Windows 7 altında bunu yapmak için doğru bir yol var?, Windows 7'nin DLL arama yolları

Ben bir C# uygulaması var

Senaryo, en WonderApp diyelim.

WonderApp C:\MyPath bulunan C++ DLL, çağırmak gerekiyor. Ayrıca DLL için dizinleri aramasına eklemek gerekir PATH bir dizin ekleyerek this article göre

Environment.SetEnvironmentVariable("PATH", 
    "C:\\MyPath;" + Environment.GetEnvironmentVariable("PATH")); 

: Yani WonderApp en Program.Main() parçası olarak, ben aşağıdaki komutu eklendi.

çözüm Windows XP çalışıyor: Ben PATH dizini eklerseniz, DLL yükler ve program gayet güzel çalışıyor. Dizini eklemezseniz, DLL, "bulunamadı" hatasıyla başarısız oluyor. Bu yüzden düşündüm

Ancak bu en SetDllDirectory() kullanarak deneyelim,

Windows 7 için çalışmaz. Şunun gibi:

[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] 
private static extern bool SetDllDirectory(string lpPathName); 

Ve daha ilerde:

bool success = SetDllDirectory(Util.Paths.GetApplicationDataDir()); 

success değeri true olmakla DLL hala yüklenmemesi.

Son olarak, uygulamayı çalıştırmadan önce PATH'u C:\MyPath'u dahil edecek şekilde ayarladıysam, her şey işe yarıyor! DLL yükler ve yalnızca iyi çalışır.

Yani, yeniden yinelerler için:

geçici Windows 7 altında DLL arama yollarına bir dizin eklemek için doğru yolu var mı?

GÜNCELLEME: Process Explorer kullanarak, uygulamanın çalışma zamanı Ortamı kontrol etti ve "C: \ MyPath" PATH gerçekten de oldu! Dahası, Helper.dll'un açık tutamaçları (DLL dosyası olarak değil, sadece bir dosya) listesinde olduğunu gördüm ve yine de onu bulmamaya karar verdiler.

+0

bu Windows'un 64-bit sürümü mı görüyor musunuz? Gerçek yol adı nedir? –

+0

Bu, 32 bit Windows 7 Home'dur. Ve DLL dosyasının tam yolu C: \ MyPath \ Helper.dll – scraimer

+0

belki de diğer dlls eksik "help.exe" programında helper.dll yüklemeyi deneyin ve diğer dlls bağımlılıklarını kontrol edin. – OlimilOops

cevap

0

Benim çözüm basit ... biliyorum, ama bunun başvurmadan komik hissediyorum. Ben Çevre değiştiren başka bir derleme, "Shell", yazdım

, WonderApp ve çıkışları çalışır.Ana uygulama (WonderApp) çalıştırılmadan önce, PATH değiştirilerek, ana uygulamanın DLL arama yolu, değiştirilen PATH'a eklenen dizinleri içerir.

Bu şuna benzer:

namespace shell 
{ 
    static class program 
    { 
     [dllimport("kernel32.dll", charset = charset.auto, setlasterror = true)] 
     public static extern bool setenvironmentvariable(string lpname, string lpvalue); 

     private static string joinargstosinglestring(string[] args) 
     { 
     string s = string.empty; 
     for (int i = 0; i < args.length; ++i) 
     { 
      if (!string.isnullorempty(s)) 
      { 
       s += " "; 
      } 
      s += "\"" + args[i] + "\""; 
     } 
     return s; 
     } 

     [stathread] 
     static void main(string[] args) 
     {  
     string pathbefore = environment.getenvironmentvariable("path"); 
     string wewant = util.paths.getapplicationdatadir() + ";" + pathbefore; 
     setenvironmentvariable("path", wewant); 

     Process process = Process.Start(".\\WonderApp.exe", joinArgsToSingleString(args)); 
     } 
    } 
} 

ben daha iyi bir çözüm bulmak isterdim!

1

Ben izin problemleri ile ilgisi var düşünüyorum.

deneyin UAC kapatma ve yeniden kodunuzu çalışan. Çalışılan yolun güncellenip güncellenmediğini kontrol edin. Eğer öyle olsaydı

, en azından başlatmak için nereye

+0

Hayır - kapanış UAC işe yaramadı. Yine de fikir için teşekkürler. – scraimer

2

'AssemblyResolve' olayını kullanarak bir C# uygulamasına özel DLL yükleme mantığı ekleyebilirsiniz. Eğer yaptığı gibi http://support.microsoft.com/kb/837908

, bir çalışan C# uygulamasının PATH ortam değişkeni değiştirme DLL arama davranışını etkilemez bulduk:

Bu sayfa kod örnekleri ile iyi bir özetini vardır. Belki de AppDomain başlangıçta PATH değerini önbelleğe alır mı? Bu konuda çalışmak için AssemblyResolve olayını kullanabilirsiniz.

da How to add folder to assembly search path at runtime in .NET?

+0

Bu harika * !!! Bana haber verdiğiniz için çok teşekkür ederim! Bu, herhangi bir .NET derlemesinde çalışacak gibi görünüyor, ancak bunun .NET dışındaki DLL'ler için de test edilmesi gerekiyor. – scraimer

+1

Tamam, kötü haber: Sadece .NET derlemeleri için çalışır. Adını göz önünde bulundurarak mükemmel bir anlam ifade eder. Bu harika bir çözüm, ancak kullanamıyorum DLL'leri .NET derlemeleri değil, çünkü kullanamıyorum. (Ve daha da kötüsü yapmak için, bu DLL'lerin de onlarla aynı dizinde bulunan diğer DLL'leri yüklemeleri gerekir, o yüzden de oraya da arama yapmaları için bir yol bulmalıyım). – scraimer