Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu konu, eski Visual Studio C++ projelerini Visual Studio'nun en son sürümüne yükseltme işlemini gösteren bir dizi makalenin ikincisidir. Bu konudaki örnek kod en son Visual Studio 2005 ile derlendi.
COMSpy
COMSpy, bir makinede hizmet veren bileşenlerin etkinliğini izleyen ve günlüğe kaydeden bir programdır. Hizmet veren bileşenler, bir sistemde çalışan COM+ bileşenleridir ve aynı ağdaki bilgisayarlar tarafından kullanılabilir. Bunlar, Windows Denetim Masası Bileşen Hizmetleri işlevselliği tarafından yönetilir.
1. Adım. Proje dosyasını dönüştürme
Proje dosyası kolayca dönüştürülür ve bir geçiş raporu oluşturur. Raporda ilgilenmemiz gerekebilecek sorunlar hakkında bilgi veren birkaç girdi vardır. Burada bildirilen bir sorun verilmiştir (bu konu boyunca, hata iletilerinin okunabilirlik için bazen kısaltıldığını, örneğin tam yolları kaldırıldığını unutmayın):
ComSpyAudit\ComSpyAudit.vcproj: MSB8012: $(TargetPath) ('C:\Users\UserName\Desktop\spy\spy\ComSpyAudit\.\XP32_DEBUG\ComSpyAudit.dll') does not match the Librarian's OutputFile property value '.\XP32_DEBUG\ComSpyAudit.dll' ('C:\Users\UserName\Desktop\spy\spy\XP32_DEBUG\ComSpyAudit.dll') in project configuration 'Unicode Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).
Projeleri yükseltmede sık karşılaşılan sorunlardan biri, proje özellikleri iletişim kutusundaki Bağlayıcı Çıktı Dosyası ayarının gözden geçirilmesi gerekebileceğidir. Visual Studio 2010'un önceki projelerde OutputFile, standart olmayan bir değere ayarlanmışsa otomatik dönüştürme sihirbazının sorun duyduğu bir ayardır. Bu durumda, çıkış dosyalarının yolları standart olmayan bir klasöre XP32_DEBUG olarak ayarlanmıştır. Bu hata hakkında daha fazla bilgi edinmek için Visual Studio 2010 proje yükseltmesi ile ilgili bir blog gönderisine başvurmuştuk. Bu, vcbuild'den msbuild'e yapılan önemli bir değişikliktir. Bu bilgilere göre, yeni bir proje oluşturduğunuzda Çıkış Dosyası ayarının varsayılan değeri olur$(OutDir)$(TargetName)$(TargetExt), ancak dönüştürülen projelerin her şeyin doğru olduğunu doğrulaması mümkün olmadığından dönüştürme sırasında bu ayarlanmaz. Ancak, outputfile için bunu eklemeyi deneyelim ve çalışıp çalışmadığını görelim. Öyle, böylece devam edebiliriz. Standart olmayan bir çıkış klasörü kullanmanın belirli bir nedeni yoksa standart konumu kullanmanızı öneririz. Bu durumda, taşıma ve yükseltme işlemi sırasında çıkış konumunu standart olmayan konum olarak bırakmayı seçtik; $(OutDir) XP32_DEBUG klasörüne çözümler Sürüm yapılandırması için yapılandırma ve ReleaseU klasöründe hata ayıklama.
2. Adım. Derlemeye alma
Taşınabilir projeyi oluştururken bir dizi hata ve uyarı oluşur.
ComSpyCtl bu derleyici hatası nedeniyle derlenemiyor:
atlcom.h(611): error C2664: 'HRESULT CComSpy::IPersistStreamInit_Save(LPSTREAM,BOOL,ATL::ATL_PROPMAP_ENTRY *)': cannot convert argument 3 from 'const ATL::ATL_PROPMAP_ENTRY *' to 'ATL::ATL_PROPMAP_ENTRY *'atlcom.h(611): note: Conversion loses qualifiersatlcom.h(608): note: while compiling class template member function 'HRESULT ATL::IPersistStreamInitImpl<CComSpy>::Save(LPSTREAM,BOOL)'\spy\spy\comspyctl\ccomspy.h(28): note: see reference to class template instantiation 'ATL::IPersistStreamInitImpl<CComSpy>' being compiled
Hata, atlcom.h dosyasındaki sınıfındaki Save yöntemine başvururIPersistStreamInitImpl.
STDMETHOD(Save)(_Inout_ LPSTREAM pStm, _In_ BOOL fClearDirty)
{
T* pT = static_cast<T*>(this);
ATLTRACE(atlTraceCOM, 2, _T("IPersistStreamInitImpl::Save\n"));
return pT->IPersistStreamInit_Save(pStm, fClearDirty, T::GetPropertyMap());
}
Sorun, derleyicinin daha eski bir sürümünün kabul edildiği dönüştürmenin artık geçerli olmamasıdır. C++ standardına uymak için daha önce izin verilen bazı kodlara artık izin verilmiyor. Bu durumda, sabit olmayan bir işaretçiyi, sabit işaretçi bekleyen bir işleve geçirmek güvenli değildir. Çözüm, sınıfında bildirimini IPersistStreamInit_SaveCComSpy bulmak ve const değiştiricisini üçüncü parametreye eklemektir.
HRESULT CComSpy::IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */, const ATL_PROPMAP_ENTRY* pMap)
ve ile benzer bir değişiklik IPersistStreamInit_Load.
HRESULT IPersistStreamInit_Load(LPSTREAM pStm, const ATL_PROPMAP_ENTRY* pMap);
Sonraki hata kayıtla ilgilidir.
error MSB3073: The command "regsvr32 /s /c "C:\Users\username\Desktop\spy\spy\ComSpyCtl\.\XP32_DEBUG\ComSpyCtl.lib"error MSB3073: echo regsvr32 exec. time > ".\XP32_DEBUG\regsvr32.trg"error MSB3073:error MSB3073: :VCEnd" exited with code 3.
Bu derleme sonrası kayıt komutuna artık ihtiyacımız yok. Bunun yerine, özel derleme komutunu kaldırmamız ve bağlayıcı ayarlarında çıkışı kaydetmeyi belirtmemiz yeterlidir.
Uyarılarla ilgilenme
Proje aşağıdaki bağlayıcı uyarısını üretir.
warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification
/SAFESEH Derleyici seçeneği hata ayıklama modunda kullanışlı değildir, /EDITANDCONTINUE bu nedenle burada düzeltme yalnızca Hata ayıklama/SAFESEHdevre dışı bırakmaktır. Bunu özellik iletişim kutusunda yapmak için, bu hatayı üreten projenin özellik iletişim kutusunu açarız ve önce Yapılandırma'yı Hata Ayıklama (aslında Unicode Hatalarını Ayıkla
Derleyici, kullanım dışı bırakıldıklarına dair PROP_ENTRY_EX bizi uyarır. Güvenli değildir ve önerilen yerine olur PROP_ENTRY_TYPE_EX.
BEGIN_PROPERTY_MAP(CComSpy)
PROP_ENTRY_EX( "LogFile", DISPID_LOGFILE, CLSID_ComSpyPropPage, IID_IComSpy)
PROP_ENTRY_EX( "ShowGridLines", DISPID_GRIDLINES, CLSID_ComSpyPropPage, IID_IComSpy)
PROP_ENTRY_EX( "Audit", DISPID_AUDIT, CLSID_ComSpyPropPage, IID_IComSpy)
PROP_ENTRY_EX( "ColWidth", DISPID_COLWIDTH, CLSID_ComSpyPropPage, IID_IComSpy)
PROP_PAGE(CLSID_StockFontPage)
END_PROPERTY_MAP()
Ccomspy.h dosyasındaki kodu uygun şekilde değiştirerek COM türlerini uygun şekilde ekliyoruz.
BEGIN_PROPERTY_MAP(CComSpy)
PROP_ENTRY_TYPE_EX( "LogFile", DISPID_LOGFILE, CLSID_ComSpyPropPage, IID_IComSpy, VT_BSTR)
PROP_ENTRY_TYPE_EX( "ShowGridLines", DISPID_GRIDLINES, CLSID_ComSpyPropPage, IID_IComSpy, VT_BOOL)
PROP_ENTRY_TYPE_EX( "Audit", DISPID_AUDIT, CLSID_ComSpyPropPage, IID_IComSpy, VT_BOOL)
PROP_ENTRY_TYPE_EX( "ColWidth", DISPID_COLWIDTH, CLSID_ComSpyPropPage, IID_IComSpy, VT_UINT)
PROP_PAGE(CLSID_StockFontPage)
END_PROPERTY_MAP()
Ayrıca daha katı derleyici uyumluluk denetimlerinden kaynaklanan son birkaç uyarıya iniyoruz:
\spy\comspyctl\usersub.h(70): warning C4457: declaration of 'var' hides function parameter\spy\comspyctl\usersub.h(48): note: see declaration of 'var'\spy\comspyctl\usersub.h(94): warning C4018: '<': signed/unsigned mismatch ComSpy.cpp\spy\comspyctl\comspy.cpp(186): warning C4457: declaration of 'bHandled' hides function parameter\spy\spy\comspyctl\comspy.cpp(177): note: see declaration of 'bHandled'
Uyarı C4018 şu koddan gelir:
for (i=0;i<lCount;i++)
CoTaskMemFree(pKeys[i]);
Sorun olarak i bildirilir ve UINT olarak lCountlongbildirilir, bu nedenle imzalı/imzasız uyuşmazlık. değerini türünü kullanan ve kullanıcı kodunda olmayan değerinden lCountaldığından, türünü UINTolarak değiştirmek IMtsEventInfo::get_Countlonguygun olmaz. Bu nedenle koda bir yayın ekleriz. C stili atama, bunun gibi sayısal bir atama için yeterlidir, ancak static_cast önerilen stildir.
for (i=0;i<static_cast<UINT>(lCount);i++)
CoTaskMemFree(pKeys[i]);
Bu uyarılar, bir değişkenin aynı ada sahip bir parametreye sahip bir işlevde bildirildiği ve kafa karıştırıcı olabilecek kodlara yol açan durumlardır. Yerel değişkenlerin adlarını değiştirerek bunu düzeltildi.
3. Adım. Test etme ve hata ayıklama
Önce çeşitli menülerde ve komutlarda çalıştırıp uygulamayı kapatarak uygulamayı test ettik. Dikkate alınan tek sorun, uygulama kapatıldığında yapılan hata ayıklama onayıydı. Sorun, uygulamanın ana COM bileşeni olan nesnesinin CWindowImpl bir temel sınıfı olan için yıkıcıda CSpyConortaya çıktı. Onay hatası atlwin.h dosyasında aşağıdaki kodda oluştu.
virtual ~CWindowImplRoot()
{
#ifdef _DEBUG
if(m_hWnd != NULL)// should be cleared in WindowProc
{
ATLTRACE(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
ATLASSERT(FALSE);
}
#endif //_DEBUG
}
hWnd normalde işlevinde WindowProc sıfır olarak ayarlanır, ancak bu gerçekleşmedi çünkü varsayılan WindowProcyerine pencereyi kapatan Windows iletisi (WM_SYSCOMMAND) için özel bir işleyici çağrılır. Özel işleyici sıfır olarak ayarlı hWnd değildi. MFC'nin CWnd sınıfındaki benzer koda baktığınızda, bir pencere yok edilirken, OnNcDestroy çağrılır ve MFC'de belgelerde, geçersiz kılınırken CWnd::OnNcDestroy, pencere tutamacını pencereden ayırmak veya başka bir deyişle sıfır olarak ayarlamak dahil olmak üzere doğru temizleme işlemlerinin gerçekleştiğinden emin olmak için tabanın NcDestroyhWnd çağrılmasını önerir. Aynı onay kodu eski atlwin.h sürümünde mevcut olduğundan, bu onay örneğin özgün sürümünde de tetiklenmiş olabilir.
Uygulamanın işlevselliğini test etmek için ATL proje şablonunu kullanarak bir Serviced Bileşeni oluşturduk, ATL proje sihirbazına COM+ desteği eklemeyi seçtik. Hizmet sağlanan bileşenlerle daha önce çalışmadıysanız, bir bileşen oluşturmak ve diğer uygulamaların kullanması için sistemde veya ağda kayıtlı ve kullanılabilir bir bileşen almak zor değildir. COM Spy uygulaması, bir tanılama yardımı olarak hizmet edilen bileşenlerin etkinliğini izlemek için tasarlanmıştır.
Ardından bir sınıf ekledik, ATL Nesnesi'ni seçtik ve nesne adını olarak Dogbelirttik. Ardından dog.h ve dog.cpp'da uygulamayı ekledik.
STDMETHODIMP CDog::Wag(LONG* lDuration)
{
// TODO: Add your implementation code here
*lDuration = 100l;
return S_OK;
}
Daha sonra bunu oluşturup kaydettik (Visual Studio'yu Yönetici olarak çalıştırmanız gerekecek) ve Windows Denetim Masası'daki HizmetLi Bileşen uygulamasını kullanarak etkinleştirdik. Bir C# Windows Forms projesi oluşturduk, araç kutusundan forma bir düğme sürükledik ve bunu bir tıklama olayı işleyicisine çift tıkladık. Bileşenin örneğini açmak için aşağıdaki kodu ekledik Dog .
private void button1_Click(object sender, EventArgs e)
{
ATLProjectLib.Dog dog1 = new ATLProjectLib.Dog();
dog1.Wag();
}
Bu sorunsuz çalıştı ve COM Spy çalışır durumda ve bileşeni izlemek Dog için yapılandırıldığında etkinliği gösteren çok sayıda veri görüntülenir.
Ayrıca bkz.
Taşıma ve Yükseltme: Örnekler ve Örnek Olay İncelemeleri
Sonraki Örnek: Spy++
Önceki Örnek: MFC Karalama