Visual Studio'nun bir DLL dosyasını çıktı dizinine kopyalamasını sağlamak nasıl?


102

Harici bir DLL dosyasına dayanan bir Visual Studio C ++ projem var. Projeyi oluştururken, Visual Studio'nun bu DLL dosyasını otomatik olarak çıktı dizinine (hata ayıklama / yayınlama) kopyalamasını nasıl sağlayabilirim?

Yanıtlar:


92

Projenizde derleme sonrası bir eylem kullanın ve sorun teşkil eden DLL'yi kopyalamak için komutları ekleyin. Oluşturma sonrası eylem, toplu komut dosyası olarak yazılır.

Çıktı dizinine şu şekilde başvurulabilir $(OutDir). Proje dizini olarak mevcuttur $(ProjDir). Derleme sonrası eylemi bozmadan proje klasörünüzü kopyalayabilmeniz veya taşıyabilmeniz için, uygun olan yerlerde göreli yolları kullanmaya çalışın.


26
Ayrıca, derleme sonrası olayını Proje> Özellikler> Derleme Etkinlikleri> Derleme Sonrası Etkinliği aracılığıyla ayarlayabileceğini belirtmekte fayda var.
Phil Booth


38
Bağlantının kesilmesi durumunda: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
as

Yukarıdakileri, örneklerimde komutu kişisel olarak nasıl kullandığıma göre değiştirdim. Bu irade; kaynak kontrolü ile iyi olan salt okunur dosyaları kopyalar ve hedef dizini oluşturur (normalde gerekli değildir). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Yemek

8
Çıktı dizininde değişmeyen dosyaların gereksiz yere yeniden kopyalanmasını önlemek için / d bayrağını xCopy'ye ekleyin.
Zoey

45

$ (OutDir), VS2013'te göreceli bir yol olarak ortaya çıktı, bu yüzden istenen etkiyi elde etmek için $ (ProjectDir) ile birleştirmek zorunda kaldım:

xcopy /y /d  "$(ProjectDir)External\*.dll" "$(ProjectDir)$(OutDir)"

BTW, başlangıçta 'echo' ekleyerek komut dosyalarında kolayca hata ayıklayabilir ve derleme çıktı penceresinde genişletilmiş metni gözlemleyebilirsiniz.


3
$ (TargetDir), $ (ProjectDir) $ (OutDir) yerine geçebilir çünkü zaten her ikisinin birleşimidir.
27

/ D olmadan benim durumumda bir Erişim Reddedildi hatası veriyordu. Ancak / d belgelere göre tarih içindir. Bağlantının ne olduğundan emin değilim.
Ravi C

1
/ D'nin eklenmesi, kaynak dosya daha eski veya mevcut bir dosyayla aynıysa üzerine yazmayı önler. Hedef başka bir işlem tarafından kilitlenirse erişim reddedildi hatası oluşabilir.
Rich Shealer

7

Yukarıdaki yorumlar bölümündeki ayrıntılar, bir C ++ projesinden çıktı dll'sini aynı çözüm içindeki başka bir C # projesinin yayın ve hata ayıklama klasörüne kopyalamaya çalışırken benim için çalışmadı (VS 2013).

Aşağıdaki inşa sonrası eylemi (.dll çıktısı olan projeye sağ tıklayın) ve ardından özellikler -> yapılandırma özellikleri -> yapı olayları -> oluşturma sonrası olay -> komut satırı eklemem gerekiyordu

şimdi çıktı dll'sini iki klasöre kopyalamak için şu iki satırı ekledim:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug

5

(Bu cevap yalnızca C # için geçerlidir, C ++ için değil, üzgünüm, orijinal soruyu yanlış anladım)

Daha önce böyle DLL cehenneminden geçtim. Son çözümüm, yönetilmeyen DLL'leri yönetilen DLL'de ikili kaynaklar olarak depolamak ve program başladığında bunları geçici bir klasöre çıkarmak ve elden çıkarıldığında bunları silmekti.

Bu , çok kullanışlı olduğu için .NET veya pinvoke altyapısının bir parçası olmalıdır .... Yönetilen DLL'nizin hem Xcopy kullanarak hem de daha büyük bir Visual Studio çözümünde Proje referansı olarak yönetilmesini kolaylaştırır. Bunu yaptıktan sonra, derleme sonrası olaylar için endişelenmenize gerek kalmaz.

GÜNCELLEME:

Kodu buraya başka bir cevapta gönderdim https://stackoverflow.com/a/11038376/364818


1
Kabul ediyorum, çerçevenin bir parçası olmalı (dll'leri statik olarak bağlamak, vb.) - Dikkat edilmeli, dll'yi bir kaynak olarak depolamak ve ardından çalışma zamanında çıkarmak, bazı kurumsal ortamlarda sorunlara neden olabilir (özellikle proaktif anti-virüs yazılımı).
BrainSlugs83

1

Project.csproj dosyasına yerleşik COPY ekleyin :

  <Project>
    ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Debug\bin" SkipUnchangedFiles="false" />
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Release\bin" SkipUnchangedFiles="false" />
    </Target>
  </Project>


0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Ayrıca göreceli bir yola da başvurabilirsiniz, sonraki örnek DLL'yi proje klasörünün bir seviye üzerinde bulunan bir klasörde bulacaktır. DLL'yi tek bir çözümde kullanan birden çok projeniz varsa, bu, DLL'nin kaynağını, bunlardan herhangi birini Başlangıç ​​Projesi olarak ayarladığınızda ulaşılabilir ortak bir alana yerleştirir.

xcopy /y /d  "$(ProjectDir)..\External\*.dll" "$(TargetDir)"

/yOnay almadan seçenek kopyalar. /dBir dosya hedefte varsa ve sadece kopya yaparsa kaynak hedeften daha yeni zaman damgası varsa opsiyon denetler.

Visual Studio'nun VS2109 gibi en azından daha yeni sürümlerinde $(ProjDir)tanımsız olduğunu ve $(ProjectDir)bunun yerine kullanılması gerektiğini buldum .

Bir hedef klasörü içinde bırakmak xcopyvarsayılan olarak çıktı dizinine bırakılmalıdır. $(OutDir)Tek başına mantığın yardımcı olmadığını anlamak önemlidir .

$(OutDir), en azından Visual Studio'nun son sürümlerinde, çıktı klasörüne giden göreceli bir yol olarak tanımlanır bin/x86/Debug. Hedef olarak tek başına kullanmak proje çıktı klasöründen başlayarak yeni bir klasör kümesi oluşturacaktır. Ör: … bin/x86/Debug/bin/x86/Debug.

Bunu proje klasörüyle birleştirmek sizi doğru yere götürmelidir. Ör: $(ProjectDir)$(OutDir).

Bununla birlikte $(TargetDir), çıktı dizinini tek adımda sağlayacaktır.

Microsoft'un Visual Studio'nun geçerli ve önceki sürümleri için MSBuild makroları listesi

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.