Bağımlı DLL, Visual Studio'daki derleme çıktı klasörüne kopyalanmıyor


188

Bir görsel stüdyo çözümüm var. Çözümde birçok projem var. Başlangıç ​​olarak hareket eden ve diğer projeleri kullanan bir ana proje var. "ProjectX" diyen bir proje var. Referansı ana projeye eklenmiştir. ProjectX, çözümün bir parçası olmayan başka bir .NET dll (say abc.dll) başvurur.

Şimdi bu abc.dll ana projenin bin / debug klasörüne kopyalanmalıdır, ancak orada kopyalanmıyor. Neden kopyalanmıyor, bilinen herhangi bir neden?


Eğer bunu anlayamıyorsanız, o zaman ön yapınıza kopyalayın.
Dilshod

'ProjectX'inizi ana projede nasıl kullanıyorsunuz - projenin türü, hedefi vb.
NSGaga-çoğunlukla etkin olmayan

Aynı sorunu yaşadım ve bu cevap sorunumu çözdü: stackoverflow.com/a/8213977/174469
Gordon Tucker


orada RestoreProjectStyle mevcut çözüm . Fikir <RestoreProjectStyle>PackageReference</RestoreProjectStyle>çözümdeki her .Net Framework projesi için ayarlamaktır .
oleksa

Yanıtlar:


105

ProjectX abc.dll başvurdu ama doğrudan abc.dll DEFINED türlerinden birini kullanmadıysanız, o zaman abc.dll ana çıkış klasörüne kopyalanmayacağını buldum. (Ekstra kafa karıştırıcı hale getirmek için ProjectX çıktı klasörüne kopyalanır.)

Bu nedenle, açıkça ProjectX'te herhangi bir yerde abc.dll türlerinden birini kullanmıyorsanız, ProjectX dosyalarından birinde bir yere kukla bir bildirim koyun.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

Her sınıf için bunu yapmanız gerekmez - sadece bir kez DLL kopyasını yapmak için yeterli olacak ve her şey beklendiği gibi çalışacaktır.

Ek: Bunun hata ayıklama modu için işe yarayabileceğini, ancak serbest bırakılmayacağını unutmayın. Ayrıntılar için @ nvirth cevabına bakınız.


7
Bu bir hack gibi görünüyor. Ana projeye referans eklemek yeterli görünmektedir.
Mike K

3
Bu bir hack, ama bugünün CodeProject haberleri bize öğrettiği gibi, derleyiciler bile yanlış olabilir!
Derebeyi Zurg

4
Ne kadar çılgınca şeyler olabilir. @OverlordZurg XAML (WPF) bağımlı dll bir referans vardı gibi çözüm çalıştı ve ben söylediğim gibi basit bir kukla referans ekleyin kadar ana projeye DLL kopyalamadı ... Yine de teşekkürler
Mohsen Afshin

5
@MohsenAfshin Ben aynı sorunu vardı --- XAML bağımlı bir DLL atıfta. Bununla birlikte, kukla bir değişken bildirmek yerine, XAML'de kullandığım bileşeni adlandırdım ve bu, montajının kopyalanmasına neden olmak için yeterliydi.
redcurry

5
@MikeK Ana projeye eklemek (aslında doğrudan ona bağlı değildir) daha da büyük bir hack, imo. Sonra iki yerde yönetmek zorunda (yükseltme veya kaldırma gibi "yönetmek"). İle bu hack, en azından size bağımlılık kaldırdığınızda bu kesmek kaldırmak için hatırlatan güzel bir derleme zamanı hatası alıyorum ve hala sadece bir yerde güncellemeniz gerekir.
jpmc26

71

Overlord Zurg'un cevabına bir ipucu.

Kukla referansı bu şekilde ekledim ve Hata Ayıklama modunda çalıştı:

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

Ancak Release modunda, bağımlı dll hala kopyalanmadı.
Ancak bu işe yaradı:

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

Bu bilgi aslında bana anlaması için saatler sürdü, bu yüzden paylaştığımı düşündüm.


7
serbest bırakma modunda, iyileştirici "kukla" kullanılmadığını varsayar, bu nedenle bu satır gereksizdir ve kaldırılmalıdır. ancak kodda "kukla" kullandığınızda, optimizer gereksiz olduğunu varsaymaz.
Yucel

1
Bu benim için işe yaramıyor.AbcDll.AnyClass hala başka bir projeye kopyalanmadı
Matthew Lock

3
AbcDll.AnyClassGenel bir sınıfta ortak alan veya mülk olarak kullanıldığından emin olun , sonra çalışır. Böyle bir yöntem vücutta kullanırsanız derleyici gelmez görüyorum . Bu montajı geciktirecek, olmasını istediğiniz şeyi değil.
John Leidegren

52

Evet, ayarlamanız Copy Localgerekir true. Ancak, eminim ki bu montajı ana projeden referans almanız ve buna da ayarlamanız Copy Localgerekir true- sadece bağımlı bir montajdan kopyalanamaz.

Aşağıdaki Copy Localmontajı tıklayıp ReferencesF4 tuşuna basarak tesise ulaşabilirsiniz.


2
@Brij, derleme istediğiniz ana projeden referans alıyor mu? Belirttiğim gibi , bu projeden referans almanız gerektiğinden eminim , ayrıca bağımlı meclisler bu şekilde kopyalanmıyor. Bu durumda NuGet'i kullanırken montajları ilgili tüm projelere eklemeniz gerekmeyecekti.
Mike Perrenoud

1
buradaki sonuç neydi? Bana öyle geliyor ki, CopyLocal true olarak ayarlanmış olsa bile, sağa bağımlı referanslar kopyalanmıyor - bunun arkasındaki mantık nedir?
mcmillab

29
@mcmillab, kısa Visual Studio değildir anlaması diğer bağımlı projelerden bağımlılıkları. A projesi B projesine referans veriyorsa A projesinin B projesinin tüm referanslarına sahip olması gerekir. Tüm B projesi ihtiyacı .NET derlemeleri olduğunda iyi çalışır, ancak 3. taraf bir derleme ise her iki projeye de referans eklemeniz gerekir.
Mike Perrenoud

12
@MichaelPerrenoud Bunun doğru olduğunu düşünmüyorum. Ayrıntılı bir MSBuild çıktısına bakarsanız, ResolveAssemblyReference aracının "ikinci ve n. Sıra bağımlılıkları içerdiğini" belirten çağrıları görürsünüz . Bu aynı zamanda bin klasörlerimde gördüklerimle de uyumludur (n-th bağımlılıkları kopyalanır). Sorun, çoğunlukla GAC ​​ve dolaylı referanslar etrafında kopyalananlar hakkında bazı uyarılar var (Referans Ekle bazen yeterli değildir)
Jack Ukleja

2
Şu anki deneyimim, bunun 'kopyalanan' bağımlılıklar dışında çalışacağıdır : proje A.net, harici C ++ dll'lerine 'her zaman kopya' olan dosyalar olarak başvuruyor. Proje B.net başvuruları Proje A. başvuruyor. B / Debug derleme C ++ dlls içerir. Ancak, Project B başvuruyor, X uygulama dll, C ++ dlls bazen kopyalanır (yalnızca bir yeniden oluşturma yapar gibi görünüyor).
Benjol

34

Bir montaj özelliği haline getirdiğinizde kaygan görünüyor

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

Kullanım:

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

Teşekkür ederim, ama benim için bu sadece zaten AbcDll.AnyClass referans bağımlılık (Project X) derleme özniteliği eklediğimde bir şey yapar. Ve sonra, AbcDll'i bağımlılığın çıktı dizinine kopyaladığı normalden daha fazlasını yapmaz. Hala ana bağımlı projenin çıktısına kopyalamıyor. Ayrıca AbcDll için bir başvuru eklemedikçe özniteliği bağımlı derleme ekleyemezsiniz. Bunu yaptığımda, AbcDll zaten öznitelik olmadan kopyalanır.
JS

25

Aynı sorunla karşılaştı. Arka plan bilgisi: Binaya başlamadan önce, çözüme yeni bir Proje X ekledim. Proje Y, Proje X'e ve Proje A, B, C Proje Y'ye bağlıydı.

Derleme hataları Proje A, B, C, Y ve X dll'lerinin bulunamamasıydı.

Temel neden, yeni oluşturulan Project X'in .NET 4.5'i hedeflerken, diğer çözüm projeleri .NET 4.5.1'i hedeflemiştir. X Projesi, projelerin geri kalanının da inşa edilmemesine neden olacak şekilde inşa edilmedi.

Yeni eklenen Projelerin, çözümün geri kalanıyla aynı .NET sürümünü hedeflediğinden emin olun.


1
Başvurulan projeler .NET'in eski bir sürümü olabilir. .NET 4.5 için oluşturulmuş bir proje tarafından .NET 4 için oluşturulmuş bir projeye başvurabiliyorum.
redcurry

18

Bu yardımcı olur emin değilim ama benim için, birçok kez bir DLL (ki otomatik olarak bin klasörüne ekler tabii) başvuru. Ancak, DLL ek DLL'lere ihtiyaç duyabilir (kullandığım işlevlere bağlı olarak). Sadece aslında kullandığım DLL ile aynı klasöre sonunda gerekir çünkü benim Proje bu referans istemiyorum.

Bunu Visual Studio'da "Varolan bir dosyayı ekleyerek" başardım. Add_data klasörü dışında herhangi bir yere ekleyebilirsiniz. Şahsen ben sadece köküne ekliyorum.

Sonra bu dosyanın özelliklerini ... olarak değiştirin.

Build Action = None (bu ayarın Content gibi bir şeye sahip olması aslında "root" sürümünü kök dizinine ve Bölmedeki bir kopyasını kopyalar).

Çıktı klasörüne kopyala = Daha yeni ise kopyala (Temelde yalnızca eksikse BIN klasörüne koyar, ancak bundan sonra yapmaz)

Ne zaman yayımlamak .. benim eklediğim DLL dosyaları sadece BIN klasöründe ve başka bir yerde Yayınla konumunda (istediğim budur) var.


10

Ayrıca, aradığınız DLL dosyalarının GAC'ye dahil olmadığından emin olabilirsiniz. Visual Studio, oluşturma makinesindeki GAC'de zaten varsa bu dosyaları kopyalamama konusunda akıllı olduğuna inanıyorum.

Kısa süre önce, GAC'da montajların bulunması gereken bir SSIS paketini test ettiğim bu durumda koştum. O zamandan beri unutmuştum ve neden bu DLL'lerin bir derleme sırasında çıkmadığını merak ediyordum.

GAC'de neler olduğunu kontrol etmek için (bir Visual Studio Geliştirici Komut İsteminden):

gacutil -l

Veya okumayı kolaylaştırmak için bir dosyaya çıktı alın:

gacutil -l > output.txt
notepad.exe output.txt

Bir montajı kaldırmak için:

gacutil -u MyProjectAssemblyName

Ben de, bir kez (onlar doğrudan kök projede doğrudan başvurulmamış derlemeler için) sonra derleme \ bin dizininde doğru çıktı GAC dosyaları kaldırıldı, dikkat etmeliyim. Bu, Visual Studio 2013 Güncelleştirme 5'teydi.


Teşekkürler, haklısın, MSBuild gll içinde bulursa çıkış klasörüne dll kopyalamak olmaz.
John-Philip

3

Benim durumumda, kabul etmediğim TFS / VS'nin varsayılan davranışından kaynaklanan en aptalca şeydi.

Ana projeye bir başvuru olarak dll eklemek işe yaramadı beri, ben Yerel Kopyala = Her zaman, bir "Mevcut Öğe" olarak eklemeye karar verdi. O zaman bile dosya orada değildi.

Dosya VS Çözümünde mevcut olsa ve hem yerel hem de sunucuda derlenen her şey olsa da, VS / TFS'nin dosyayı kaynak kontrolüne gerçekten eklemediğini ortaya koyuyor. "Bekleyen Değişiklikler" e hiç dahil edilmedi. Manuel olarak Kaynak Kontrol Gezgini'ne gitmem ve "Klasöre öğe ekle" simgesine tıklamam gerekiyordu.

Aptal çünkü VS'de 15 yıldır gelişiyorum. Daha önce bunun içine girdim, sadece hatırlamadım ve bir şekilde kaçırdım çünkü dosya düzenli bir referans olduğu için her şey hala derlendi, ancak mevcut öğe olarak eklenen dosya mevcut olmadığı için kopyalanmadı kaynak kontrol sunucusu.

Umarım bu biraz zaman kazandırır, çünkü hayatımın 2 gününü buna kaybettim.


1
Sana yeterince teşekkür edemem ... beni çok fazla kurtardın. Bu benim için bir çözümdü. Ayrıca kök sorununu ortaya çıkardı, referans olarak eklediğim DLL bir gitignoredesenle eşleşti , bu yüzden referans olarak eklerken projeye eklenmedi. El ile dosyayı kaynak denetimine eklemeniz GEREKİR !!!
Mattkwish

2

Bu nvirth örneğinde hafif bir değişiklik

internal class DummyClass
{
    private static void Dummy()
    {
        Noop(typeof(AbcDll.AnyClass));
    }
    private static void Noop(Type _) { }
}

2

Çıkış dizinlerine gerekli kütüphaneleri kopyalamak için Postbuild olaylarına ekleyeceğim. XCopy pathtolibraries targetdirectory gibi bir şey

Bunları proje özelliklerinde bulabilirsiniz -> Etkinlik Oluştur.


Bu benim için çalıştı ve bence bu daha iyi bir yanıt. Kukla referans çözümü işe yarıyor, ancak bu bir hack, ancak bir post-build kuralı aynı sonucu elde etmek için temiz bir yoldur.
Kevin Fichter

2

Konu:

Yapı çıktısının başvurulan DLL dosyasını içermediği bir NuGet paket DLL dosyası (Newtonsoft.json.dll) için benzer bir sorunla karşılaşıldı. Ama derleme iyi gidiyor.

Düzeltme:

Projelerinizi bir metin düzenleyicide gözden geçirin ve içinde etiketleri olan referansları arayın. Doğru veya Yanlış gibi. “Özel”, “Yerel Kopyala” ile eşanlamlıdır. Eylemlerin bir yerinde, MSBuild bağımlılıkları bulmaya çalışıyor, bağımlılığınızı başka bir yerde buluyor ve kopyalamamaya karar veriyor.

Bu nedenle, her .csproj / .vbproj dosyasını gözden geçirin ve etiketleri manuel olarak kaldırın. Yeniden oluştur ve her şey hem Visual Studio hem de MSBuild'de çalışır. Çalışmaya başladıktan sonra, geri dönüp olması gerektiğini düşündüğünüz yere güncelleyebilirsiniz.

Referans:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/


1

KODDA Kukla GEREK YOK
Sadece:

Yürütülebilir Projeye Başvuru ekleme

veya / ve çalıştırılabilir projedeki referansın ("benim hatam " olduğu) "Copy Local"ayarlandığından emin olun , bu temeldeki kütüphane-projedeki ayarın "üzerine yazılmıştır" ...TRUE


1

Başvurulan derlemeyi sağ tıklatırsanız, Yerel Kopyala adlı bir özellik görürsünüz . Yerel Kopyala true olarak ayarlanırsa, montaj bölmeye dahil edilmelidir. Ancak , bazen bin klasörüne başvurulan dll'yi içermeyen Visual studio ile ilgili bir sorun olması için dikişler var ... bu benim için çalışan geçici çözüm:

resim açıklamasını buraya girin


1
Kopya Kopyalama devre dışı bırakıldı, bu yardımcı oldu stackoverflow.com/questions/15526491/…
codemirror

1

TLDR; Visual Studio 2019'un yeniden başlatılması gerekebilir.

Microsoft.NET.Sdk projesine dayalı projeleri kullanarak bu durumla karşılaştım.

<Project Sdk="Microsoft.NET.Sdk">

özellikle:

  • Project1: hedefler .netstandard2.1
    • Microsoft.Extensions.Logging.ConsoleNuget üzerinden referanslar
  • Project2: hedefler .netstandard2.1
    • Referanslar Project1proje referans ile
  • Project2Tests: hedefler .netcoreapp3.1
    • Referanslar Project2proje referans ile

Test yürütme, I belirten hata mesajı aldığı Microsoft.Extensions.Logging.Consolebulunamadı, ve gerçekten de değil çıkış dizinde.

Dosyada bulunmasına rağmen , yalnızca Visual Studio'nun Nuget Manager uygulamasının yüklü olarak listelemediğini keşfetmek Microsoft.Extensions.Logging.Consoleiçin ekleyerek sorunu Project2çözmeye karar verdim .Microsoft.Extensions.Logging.ConsoleProject1Project1.csproj

Visual Studio'nun basit bir kapatılması ve yeniden başlatılması, ek bir başvuru eklemeye gerek kalmadan sorunu çözdü. Belki bu 45 dakika kayıp üretkenlik kurtaracak :-)


Aslında şeyleri test etme yolunda tüm bilgisayarı yeniden başlattım ama benim için çalıştı
Noman_1

0

Aynı projeye hem ana projeyi hem de ProjectX'in derleme çıktı yolunu ayarlayabilirsiniz, sonra o klasörde ihtiyacınız olan tüm dll'leri alabilirsiniz.


0

Kullandığınız bağımlı dll'nin projenizin Uygulamasının hedef .net çerçevesinden daha yüksek hedef .net çerçevesine sahip olmadığından emin olun.

Projenizi seçip ALT + ENTER tuşlarına basın, ardından sol taraftan Uygulama'yı seçin ve ardından projenizin Hedef Çerçevesini seçin.

Diyelim ki, bağımlı dll Hedef Çerçeve = 4.0 ve Uygulama dll Hedef Çerçeve = 3.5 sonra bunu 4.0 olarak değiştirin

Teşekkür ederim!


0

Yukarıda sıralananlardan başka, yayınlamak için çok projeli bir çözümüm vardı. Görünüşe göre bazı dosyalar farklı çerçeveleri hedefliyor.

Benim çözümüm: Özellikler> Özel Sürüm (Yanlış)



0

VS2019 V16.6.3

Benim için sorun bir şekilde ana .proj dosyası, DLL'i üst proje bin klasörüne kopyalanmayan proje için böyle bir girişle sonuçlandı:

<ProjectReference Include="Project B.csproj">
  <Project>{blah blah}</Project>
  <Name>Project B</Name>
  <Private>True</Private>
</ProjectReference>

Hattı manuel olarak sildim <Private>True</Private> ve DLL daha sonra ana projenin her yapısında ana proje bin klasörüne kopyalandı.

Ana projenin başvurular klasöründe sorunlu projenin başvurusuna giderseniz, projeyi tıklatın ve özelliklerini görüntülemek bir "Yerel Kopyala" ayarı vardır. Özel etiket bu ayara eşittir, ancak bazı nedenlerden dolayı yerel kopya değiştirmenin .proj dosyasındaki özel etiket üzerinde hiçbir etkisi olmamıştır.

Can sıkıcı bir şekilde referans için kopya yerel değerini değiştirmedim, bu şekilde nasıl ayarlandığı hakkında hiçbir fikrim yok ve başka bir gün VS ile aptalca bir sorunu izleyerek boşa harcadım.

Beni davaya sokmaya yardımcı olan diğer tüm cevaplar sayesinde.

HTH

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.