Visual StudioでXAMLファイルを開くと、通常はXAMLのソースコードを直接編集できる「XAMLコードエディター」とレイアウトの概要が表示される「XAMLデザイナー」が表示されます。ところが、ある特定のPCだけ、「XAMLデザイナー」が例外が発生し起動しない状態がずっと続いていました。すごく不便だったのですが、原因がわかりました。その解決方法です。Visual StudioでWPFやUWPのXAMLファイルを開くと、
- XAMLのソースコードを直接編集できる「XAMLコードエディター」
- レイアウトの概要が表示される「XAMLデザイナー」
が表示されます。例えば、あるアプリの MainWindow.xaml を開くと以下のように上限に分割されて「XAMLコードエディター」と「XAMLデザイナー」が表示されます。
この絵のように、コードエディターとデザイナーが同時に表示されるので、レイアウトを確認しながら、効率よくXAMLコードを書くことができます。ちなみに私は、修正はすべてコードエディターで行い、XAMLデザイナーは、レイアウトの確認のみに使用しています。
ところが、私の使用している複数のPCの中で、特定の一台のPCのみXAMLデザイナーが表示されません。以下の絵のように、例外が発生してエラー画面になります。
例外の内容は、二つのパターンがあるようです。一回目は以下のように、「System.Runtime.Remoting.RemotingException [] Designer process terminated unexpectedly!」の例外が発生します。
System.Runtime.Remoting.RemotingException [] Designer process terminated unexpectedly! at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.ProcessDomainFactory.ProcessIsolationDomain.Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IIsolationDomain.CreateInstance(String assemblyName, String assemblyCodeBase, String typeName) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.IsolationBoundary.Initialize() at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.IsolationBoundary.CreateInstance[T](Type type) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedObjectFactory.Initialize() at Microsoft.VisualStudio.DesignTools.DesignerHost.Services.VSIsolationService.CreateObjectFactory(IIsolationDomainFactory isolationDomainFactory, IObjectCatalog catalog) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolationService.CreateLease(IIsolationDomainFactory domainFactory) at Microsoft.VisualStudio.DesignTools.DesignerContract.IsolatedDesignerService.CreateLease(IIsolationDomainFactory domainFactory, CancellationToken cancelToken, DesignerServiceEntry& entry, IServiceProvider serviceOverrides) at Microsoft.VisualStudio.DesignTools.DesignerContract.IsolatedDesignerService.IsolatedDesignerView.CreateDesignerViewInfo(CancellationToken cancelToken) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedTaskScheduler.InvokeWithCulture[T](CultureInfo culture, Func`2 func, CancellationToken cancelToken) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedTaskScheduler.<>c__DisplayClass10_0`1.<StartTask>b__0() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.Execute()
同じVisual Studioのプロセス内で、1回目の例外が発生した後、もう一度、XAMLデザイナーを表示しようとすると以下のように、「System.ArgumentException: An item with the same key has already been added.」の例外が発生します。
System.ArgumentException An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) at Microsoft.VisualStudio.DesignTools.Utility.Telemetry.VsTelemetryService.RegisterDesignerProcessSession(Int32 pid) at Microsoft.VisualStudio.DesignTools.Utility.DesignerSessionTracker.RecordDesignerStart(Int32 processID, String isolationTargetIdentifier, String buildConfiguration) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.ProcessDomainFactory.ProcessIsolationDomain..ctor(ProcessDomainFactory factory, IIsolationBoundary boundary, AppDomainSetup appDomainInfo, IIsolationTarget isolationTarget, String baseDirectory) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.ProcessDomainFactory.CreateIsolationDomain(IIsolationBoundary boundary) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.IsolationBoundary.Initialize() at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Primitives.IsolationBoundary.CreateInstance[T](Type type) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedObjectFactory.Initialize() at Microsoft.VisualStudio.DesignTools.DesignerHost.Services.VSIsolationService.CreateObjectFactory(IIsolationDomainFactory isolationDomainFactory, IObjectCatalog catalog) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolationService.CreateLease(IIsolationDomainFactory domainFactory) at Microsoft.VisualStudio.DesignTools.DesignerContract.IsolatedDesignerService.CreateLease(IIsolationDomainFactory domainFactory, CancellationToken cancelToken, DesignerServiceEntry& entry, IServiceProvider serviceOverrides) at Microsoft.VisualStudio.DesignTools.DesignerContract.IsolatedDesignerService.IsolatedDesignerView.CreateDesignerViewInfo(CancellationToken cancelToken) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedTaskScheduler.InvokeWithCulture[T](CultureInfo culture, Func`2 func, CancellationToken cancelToken) at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.IsolatedTaskScheduler.<>c__DisplayClass10_0`1.b__0() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.Execute()
その問題が発生するPCでXAMLを編集するときはすごく不便でした。私は基本的にXAMLの編集は、「XAMLコードエディター」でしていたので、全く使えないということはありませんでした。しかし、レイアウトの概要が見れない状態でXAMLコードを編集するのはとても非効率でした。
長い間、この「XAMLデザイナー」が起動しない原因がわかりませんでした。その間に、Visual Studio 2017やVisual Studio 2015を修復インストールしてみたり、それでだめなら、アンインストール・インストールしたりしましたが、どうやっても解決できませんでした。
ところが、今回、その原因がわかりました。具体的には、
C:\Program.exe
という0バイトのファイルが存在していたことでした。このファイルを消すと「XAMLデザイナー」が問題なく表示されます。直接の原因がわかったので「XAMLデザイナー」についてもう少し調べてみました。
Visual StudioでXAMLデザイナーを起動すると、
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\XDesProc.exe
というプロセスが起動します。このプロセスがXAMLデザイナーを実現しているようです。「C:\Program.exe」とこのパスの関係からピンときました。もしかしてXDesProc.exe起動するときにパスに’ ‘(スペース)が含まれているのに”(ダブルクオーテーション)なしで起動の処理しているのではないかと。
これを検証するために「C:\Program.exe」以外に問題の発生が想定できる以下のパスも試してみました。
C:\Program Files.exe C:\Program Files (x86).exe C:\Program Files (x86)\Microsoft.exe C:\Program Files (x86)\Microsoft Visual.exe
どれでも同じ問題が起きる可能性があります。ただ、私のPCには、
C:\Program Files\ C:\Program Files (x86)\Microsoft\
の二つのフォルダが存在するので、一部はそちらが優先され問題は発生しません。実際に問題が発生するのは、最終的に
C:\Program.exe C:\Program Files.exe C:\Program Files (x86)\Microsoft Visual.exe
でした。これで、Visual Studioにおいて、スペースの処理が間違っているのが確定だと思います。
ちなみに、上記のEXEを0バイトのファイルではなく、起動できるEXEファイルを名前変更しておくと、「XAMLデザイナー」を開こうとしたときにそのEXEが起動することを確認しました。そのとき、Visual Studio上の画面は、以下の画面のようにXAMLデザイナーのロード画面(Loading designer….)のまま先に進みません。
みなさん、もし、Visual Studioの「XAMLデザイナー」が「例外で起動しない」・「ロード画面のまま進まない」ことがあったら、
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\XDesProc.exe
のパスの一部のファイルパスのEXEが存在しないか確認しましょう。存在したらそのファイルを削除または名前変更しましょう。それで解決します。ただし、Visual Studioのバージョンによってパスが異なることがあるので、注意してください。
ところで、問題が発生したPCに、なぜ、
C:\Program.exe
のファイルがあったのかという理由が皆さんにはわからないと思います。これは、dllハイジャッキング脆弱性の確認をしているときに、意図的に作成したファイルです。問題がないアプリであれば、上記のようなファイルがあっても問題なく動作するはずなのです。今回、問題が発生したアプリがVisual Studioであったのも意外でしたが。
以上、「XAMLデザイナー」が起動しないときの対処方法でした。