我試圖爲VS2017(用C#)創建一個擴展VSPackage,它將二進制數據轉換爲XML,在默認VS XML編輯器和XML語言服務中打開它,然後在保存時將其轉換回二進制文件。VSX:如何重新使用現有的XML編輯器來處理轉換爲XML的二進制文件?
但是,我有麻煩來列出哪些步驟將需要這個。我想到了創建在編輯器廠一個新的編輯器,現在以下爲:
- 創建新的文本緩衝
- 與轉換XML數據
- 創建核心編輯器給它
- 與文本餵它緩衝
現在我的嘗試是這樣的:
private MyPackage _package; // Filled via constructor
private IServiceProvider _serviceProvider; // Filled via SetSite
public int CreateEditorInstance(uint grfCreateDoc, string pszMkDocument, string pszPhysicalView,
IVsHierarchy pvHier, uint itemid, IntPtr punkDocDataExisting, out IntPtr ppunkDocView,
out IntPtr ppunkDocData, out string pbstrEditorCaption, out Guid pguidCmdUI, out int pgrfCDW)
{
// Initialize and validate parameters.
ppunkDocView = IntPtr.Zero;
ppunkDocData = IntPtr.Zero;
pbstrEditorCaption = String.Empty;
pguidCmdUI = Guid.Empty;
pgrfCDW = 0;
VSConstants.CEF createDocFlags = (VSConstants.CEF)grfCreateDoc;
if (!createDocFlags.HasFlag(VSConstants.CEF.OpenFile) && !createDocFlags.HasFlag(VSConstants.CEF.Silent))
return VSConstants.E_INVALIDARG;
if (punkDocDataExisting != IntPtr.Zero)
return VSConstants.VS_E_INCOMPATIBLEDOCDATA;
// Create a sited IVsTextBuffer storing the converted data with the XML data and language service set.
IVsTextLines textLines = _package.CreateComInstance<VsTextBufferClass, IVsTextLines>();
SiteObject(textLines);
string xmlText = BinaryXmlData.GetXmlString(pszMkDocument);
textLines.InitializeContent(xmlText, xmlText.Length);
ErrorHandler.ThrowOnFailure(textLines.SetLanguageServiceID(ref Guids.XmlLanguageServiceGuid));
// Instantiate a sited IVsCodeWindow and feed it with the text buffer.
IVsCodeWindow codeWindow = _package.CreateComInstance<VsCodeWindowClass, IVsCodeWindow>();
SiteObject(codeWindow);
codeWindow.SetBuffer(textLines);
// Return the created instances to the caller.
ppunkDocView = Marshal.GetIUnknownForObject(codeWindow);
ppunkDocData = Marshal.GetIUnknownForObject(textLines);
return VSConstants.S_OK;
}
private void SiteObject(object obj)
{
(obj as IObjectWithSite)?.SetSite(_serviceProvider);
}
// --- CreateComInstance is a method on my package ----
internal TInterface CreateComInstance<TClass, TInterface>()
{
Guid guidT = typeof(TClass).GUID;
Guid guidInterface = typeof(TInterface).GUID;
TInterface instance = (TInterface)CreateInstance(ref guidT, ref guidInterface, typeof(TInterface));
if (instance == null)
throw new COMException($"Could not instantiate {typeof(TClass).Name}/{typeof(TInterface).Name}.");
return instance;
}
當我嘗試用我的編輯器明確打開文件時,它指出「無法使用所選編輯器打開文件。請選擇另一位編輯。「這條消息對我來說沒有任何意義,我試圖用XML編輯器打開XML數據,但它仍然試圖用二進制數據打開文本編輯器。所有我能想到的給它轉換後的數據,顯然這種方式是不正確的。
- 我怎麼能添加一些步驟,其間獲取二進制數據,迅速將其轉換爲XML,然後將其輸送給XML編輯器?
- 如何在XML編輯器保存文件時將其存儲爲二進制文件?
- 是否有可能重用XML爲此編輯和語言服務?
對不起,如果這些問題需要冗長的答案;如果我可以指向正確的方向,或者已經做了一些類似的開源擴展(在將文件數據顯示在VS代碼編輯器中之前進行轉換),我會很高興。
不知道,但我會圍繞它通過破解它保存在一個臨時目錄中的XML文件,在編輯器中打開它,並觀察該文件變化。不夠優雅,但很快就可以實現。也許有人知道如何讓優雅的路線工作... – Will
是的,我想到了VSX的打擊感,但後來我可以保留我目前的外部程序來修改文件;加上我不確定這些攻擊最終是否容易實現... –