興味がありました:ブラウザの外部から実行中のsilverlightプロセスに任意のアセンブリを埋め込むことは可能ですか?
私が知る限り、silverlightにコードを埋め込む既存のプログラムはすべて、アプリケーションをロードする前に.xapファイルをインターセプトおよび変更することでこれを行います。 これは良い方法ですが、いくつかの欠点があります。
1.ページをリロードしないと、すでに実行中のアプリケーションに接続できません
2. .xapファイルをインターセプトすると、Internet Explorerのプラグインランタイムが制限されることがよくあります。 ユニバーサルインターセプターの場合は、httpスニファーを使用する必要があります。
既に実行中のアプリケーションに接続し、ページをリロードせずに、.xapファイルを変更せずに、ブラウザーの制限なしに、それを浸透できる方法を提供したいと思います。 始める前に、今日のオープンソースゲストを紹介させてください。
眠る
このコンソールプログラムは、プログラミングの好奇心の成果です。 実行中のSilverlightプロセスを選択し、Silverlightアセンブリをその中に埋め込むことができます(クリックすると大きな解像度が得られます)。
バイナリはここからダウンロードでき、C#ソースコードはgithubで入手できます。 展開を開始する前に、次のコマンドを実行してプログラムをインストールする必要があります。
slinject --install
これは、管理者権限が必要な1回限りの操作です。 インジェクターをインストールした後、どのユーザーでも実装できます。
待って、離れないで! またはそれがどのように機能するか
よくあることですが、アイデアは非常にシンプルです。 デバッガーをSilverlightプロセスに接続し、Assembly.Load()コマンドを実行します。 Visual Studioデバッガーから常に実行できますが、プログラムから実行できますか?
Silverlightには、多くの興味深いライブラリとツールがインストールされていますが、残念なことに、これらのライブラリとツールには不快なドキュメントが含まれているか、まったく含まれていません。 これらのライブラリの1つはdbgshim.dllです。 このドアを介して、デバッガーがSilverlightの世界に入ります。 Visual Studioはそれを使用するので、なぜ抜け穴を利用しないのですか? 確かに、なぜですか? 優れたドキュメントの欠如は、良い議論ではありません。 しかし、好奇心の強い人には良い挑戦です-できます。
そのため、
問題
ブレークポイントを設定するために、Silverlightプロセスで呼び出されることが保証されるメソッドをSilverlightで見つける必要がありました。 WPF / WinFormsの場合、アプリケーションは簡単です。 Windowsメッセージキューのプロセッサを取得し、ブレークポイントを設定します。 しかし、SilverlightにはWindowsメッセージキューはありません。 さいわい、JoltHelper.FireEvent()メソッドに近いものがあります。 このメソッドは、空のSilverlightアプリケーションでも呼び出され、マウスを動かすだけです。
コンソールデバッガーが式の評価を行うことができると言ったことを覚えていますか? 実際、ブレークポイント中にコードを実行するために、デバッグインフラストラクチャには多くの条件が必要です。 メソッドがfunceval'eについて最適化されていて、疑問がない場合。 JoltHelper.FireEvent()は、もちろん最適化されています:
解決策
Silverlightのジッターは、.NETの世界の兄弟のように、生成されたコードを最適化するための.iniの推奨事項に耳を傾けていることがわかりました 。 アセンブリの横に次の.INIファイルを作成するだけで十分です。
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
それを「Assembly_Name_without_dll.ini」として保存すると、次回JITコンパイル中に、生成されたコードがデバッガにとってより使いやすくなります。 最大の問題は、.iniファイルのエンコードです。 UTF-16リトルエンディアンと異なる場合、ファイルは単に無視されます。
パフォーマンスを向上させるために、Silverlightはインストール中に、標準アセンブリのマシンコードでイメージを生成します。 実際、同じngen 、ユーティリティのみcoregenと呼ばれ、生成の結果はSilverlightフォルダーに配置されます。 Coregenは、.iniの推奨事項の存在も考慮し、デバッグマシンコードを生成できます。
あなたが言うとき:
slinject --install
プログラムは、ジッターに必要な推奨事項を含むSystem.Windows.iniファイルを作成します。 古いプリコンパイル済みのSystem.Windows.ni.dllイメージを削除し、coregenにデバッグイメージを作成するように依頼します。 そしてもちろん、これらすべての変更を元に戻すには、それで十分です
slinject --uninstall
結論として
それで、Silverlightのユニバーサルアセンブリ実装者を得ましたか? ああ、いや。 ストリームを強制終了しても、ランダムな場所で中断してランダムなコードの実行を要求するよりも無害に見えます。 Mike Stallは、ブログでFuncEvalが悪であるが有用な悪である理由について語っています。 最終的に、それがVisual Studioでのウォッチ/ローカル/イミディエイトウィンドウの動作です。 この知識を武器に、slinjectを使用して、Silverlightプロセスのクラッシュ、ブラウザーのクラッシュ、および政治家のトリックに備えてください。
さらに、私はCOM'e / ICorDebug'eの専門家ではありません。 間違いなくコードに多くの間違いを犯しましたが、それはオープンソースです-エラーを表示/修正してくれたら嬉しいです。
Silverlightデバッガーの世界でこの散歩を楽しんだことを願っています。レビューを聞いてうれしいです:)。