2009-09-21 7 views
18

Tamam ibaresini, bu gerçekten rahatsız edici, ben yükleme XAML kaynakları için WPF tarafından oluşturulan kod, WPF meclislerinin yan sürümleri yana desteklemek için gereken senaryolar için sorunlu olabilir, bu nedenle güçlü isim kullanılmasını görünür ve etmediğini daha önce fark etmiştim.nasıl montaj güçlü adını kullanmak kaynak URI'lerini kullanmak WPF zorlamak için? Ahh!

Durum böyle oldu ve şimdi sorunlara neden oluyor - Yalnızca sürüm numaralarında (montaj sürümleri) farklı olan eklentilerin yan yana kurulumunu desteklemesi beklenen bir eklenti sistemim var. . montajları aynı DLL dosya adını olsa bile farklı kimlikler olması belirlenmesi nedeniyle elbette bu .NET ile desteklenebilir, bunlar kesin adlandırılmış ve farklı bir kamu/özel anahtara sahip YA farklı montaj sürüm numarasına sahip ya şartıyla. görsel stüdyo tarafından pencereler ve usercontrols için oluşturulan koda bakarsak

Şimdi, aşağıdaki otomatik oluşturulan dosyada bakın:

/// <summary> 
/// InitializeComponent 
/// </summary> 
[System.Diagnostics.DebuggerNonUserCodeAttribute()] 
public void InitializeComponent() { 
    if (_contentLoaded) { 
     return; 
    } 
    _contentLoaded = true; 
    System.Uri resourceLocater = new System.Uri("/Sensormatic.AMK1000.Panel;component/views/servicepanelui.xaml", System.UriKind.Relative); 

    #line 1 "..\..\..\Views\ServicePanelUI.xaml" 
    System.Windows.Application.LoadComponent(this, resourceLocater); 

    #line default 
    #line hidden 
} 

Uyarı kaynak bulucu oluşturulur hat - it xaml kaynağını içeren güçlü adı veya derlemenin sürümünü belirtmeyen göreceli bir URI kullanıyor.

belki LoadComponent çağıran meclisin kimliğini kontrol etmek ve genel anahtar ve versiyon detayları var ya da belki 'bu' parametresi için türünü içeren derleme kimliğini kontrol kullanmak düşündüm.

Durum böyle değil - farklı sürüm numaralarına (ancak aynı dosya adına) sahip iki derlemeniz varsa, "Kaynak X bulunamıyor" iletisiyle bir IOException alabilirsiniz (yukarıdaki örnek için "Kaynak bulunamıyor) 'views/servicepanelui.xaml'.

Daha da kötüsü, bunun aynı dosya adıyla ancak farklı ortak/özel anahtarla, yani farklı yayıncılardan oluşan derlemeler de bu hatayla sonuçlanacağı anlamına geleceğinden eminim.

Yani, herkes bu etrafında nasıl biliyor.? nasıl uyumlu WPF güçlü isim yapmak.

Not kadarıyla bana kalırsa bu bir WPF hatasıdır. Bunu önlemek için yalnızca Appdomain yalıtımını kullanmanız gerekmemelidir.

+0

Merhaba Phil, aynı sorunla karşı karşıya ediyorum. Buna herhangi bir çözüm buldunuz mu? –

+0

WPF Özel denetimlerinde Temalar'ı (Kaynak Sözlükleri aracılığıyla) kullanarak benzer bir sorunla karşılaştı mı? Evet ise, bunun için herhangi bir çözüm var mı? – akjoshi

+0

bu konuda herhangi bir haber var mı? –

cevap

3

Ben bu muhtemelen XAML kalıp bir hata ya da en azından bir eksiklik olduğunu kabul eğilimindedir. Belki de Connect numaralı telefondan bildirmelisiniz.

Potansiyel çözümlerden bir çift burada çalıştı, ancak henüz:

  1. (tam montaj bilgilerini belirtmek otomatik pack URIs kullanmak .g.cs dosyalarını değiştirmek için bir ön-derleme adımı enjekte AssemblyShortName [; Version] [; PublicKey];)
  2. AppDomain.AssemblyResolve için Ekle bileşen/Yol CLR doğru montaj bulmalarına yardımcı olmak için
+0

Teşekkürler Kent, bu işi halletmenin bir yolu olacağını umuyordum! (onu bulamadım). # 2'nin yardım edeceğini sanmıyorum - derleme çözümleme isteğinin yalnızca URI'nin belirttiği şeyden bu yana zayıf isme sahip olacağından ve sonra hangisinin olması gerektiğini bilmiyorum Kullanılmış. # 1 işe yarayabilir, belli ki çirkin olsa da. Btw, truss üzerinde büyük çalışma. Mevcut projemde kullanmak. – Phil

+0

Montaj için bağlantı kurmak, yüklemek istediğiniz bir ipucunun olmamasının bana yararlı gelmediği, belki de [[[namespace]]] 'de –

3

Bu aynı Probl, Celi Differ yaşamış em ve bu, ekte bir .xaml sayfası kullanılarak bir kontrol oluşturulduğunda olası bir çözüm olabilir.

.cs dosya yapıcısı, InitializeComponent() çağrısından önce, aşağıdaki satırları ekleyin:

 
contentLoaded = true; 
var assemblyName = GetType().Assembly.GetName(); 
System.Windows.Application.LoadComponent(GetType(), new Uri(
       string.Format("/{0};v{1};component{2}/{3}.xaml", 
       assemblyName.Name, 
       assemblyName.Version, 
       [[[namespace]]], 
       type.Name 
       ), UriKind.Relative)) 

burada [[[ad]]] olarak görsel stüdyo projesi varsayılan ad dışında sınıfın tam ad girmek

(Not: orada bir üzerinde işaretli bir açık https://connect.microsoft.com/VisualStudio/feedback/details/668914/xaml-generated-code-uses-resource-uri-without-assembly-strong-name bağlantı) oluşturulan kod URI en değiştirmek için proje dosyasında aşağıdaki ayarlayabilirsiniz

+0

belirtilirse istekte bulunan montajı kullanabilirsiniz. Eğer yüklemeye çalışıyorsanız sayfanın projeye yeri göreli bildin nasıl –

5

:

<PropertyGroup> 
    <AssemblyVersion>1.0.0.0</AssemblyVersion> 
    <AssemblyPublicKeyToken>[YOUR_PUBLIC_KEY_TOKEN]</AssemblyPublicKeyToken> 
</PropertyGroup> 
+1

(genellikle kök soyulmuş ad denk)? Bu çok .. iyi ezoterik. Bu, resmi olarak desteklenmiyor, ama işe yarıyor! – user195275

+0

Bu çözümü sevmiyorum, ya sürümümü değiştirirsem (otomatik refactor yok) ya da hata ayıklama makinemde ve yapı sunucumda farklı bir anahtar var mı? –

+0

Şimdi bir haftadan fazla bir süredir bu konu etrafında çalışıyordum ve çok acı çekiyordum! Cevabın benim için bir çekicilik gibi çalıştı ve çok yardımcı oldu! Teşekkür ederim!! (Ayrıca [bu site] notu (https: //alexfeinberg.wordpress.com/2014/11/08/microsoft-mekanizma-to-load-wpf-kaynakları-is-kırık-görünümlü-için-bir-daha iyi-başlık /), bu konuya atıfta) –

1

VS2012'de bununla uğraşıyorum. Riccardo'nın çözümünü bu ortamda çalışmak için alamadım. Onun Bu kod varyantı ...

_contentLoaded = true; 
var assemblyName = GetType().Assembly.GetName(); 
Application.LoadComponent(this, new Uri(String.Format("/{0};v{1};component/CustomersFrame.xaml", assemblyName.Name, assemblyName.Version), UriKind.Relative)); 

... 'kaynağı bulamadı' sorunu çözmek mi ama sonra çocuk eleman boyunca biraz daha ileri aşağıdaki hatayla: 'adında bir nesne kaydedilemedi. Bu kapsamda 'ad' adında yinelenen isim kaydedilemez. '

Aaron Marten'in çözüm benim için çalışır. Üzgünüm, yorum yapamıyorum veya tavsiye edemiyorum ama temsilcisi yok. senin otomatiktir yapýlar eğer Msbuild sürecine AssemblyVersion = $ versiyon parametresi:

1

Ayrıca/s geçebilir.

+0

Şimdi bu konu etrafında çalışıyordum bir haftadan fazla ve çok acı çekiyordum! Cevabın benim için bir çekicilik gibi çalıştı ve çok yardımcı oldu! Teşekkür ederim!! (ayrıca [bu site] notu (https://alexfeinberg.wordpress.com/2014/11/08/microsoft-mechanism-to-load-wpf-resources-is-broken-looking-for-a-better-title/), cevabınızı bildiren) –

+0

Blogumu ekledim – user195275

0

Bu kod, Riccardo'nın Yanıta göre, VS2010 benim için çalıştı.

Öncelikle benim XAML yapıcı çağırabileceğiniz bir yükleyici yöntemi tanımladı.
namespace Utility 
{ 
    public class Utility 
    { 
     public static void LoadXaml(Object obj) 
     { 
      var type = obj.GetType(); 
      var assemblyName = type.Assembly.GetName(); 
      var uristring = string.Format("/{0};v{1};component/{2}.xaml", 
       assemblyName.Name, 
       assemblyName.Version, 
       type.Name); 
      var uri = new Uri(uristring, UriKind.Relative); 
      System.Windows.Application.LoadComponent(obj, uri); 
     } 
    } 
} 

Daha sonra her XAML kontrolü için yapıcısı içinde, beraber InitializeComponent() değiştirilmiştir:

benim RelativeSource bağlamaları bazı çalışmayı durdurdu, ama bu geçici bir çözüm mümkün olduğunu fark etmedi
 _contentLoaded = true; 
     Utility.Utility.LoadXaml(this); 
     InitializeComponent(); 

.