プロキシ認証が必要な環境下での、ClickOnceによるアプリケーション更新
最新のClickOnceでプロキシ認証は、Windows認証のみ対応しているとされています。それ以外のプロキシ認証が必要な環境では、ローカルプロキシを経由するなどの方法を使う必要がありました。ただ、PCに明るくないユーザさんにローカルプロキシを入れよ、というのがなかなか難しい場合もあります。そんなわけで、それを乗り越える方法を書いているブログを見つけました。
http://bronumski.blogspot.com/2009/06/clickonce-updates-via-authentication.html
リンク先を読めば解決しますが、英語を読むのが面倒な人のためにこちらにも書いておきます。
まずは、自動でアプリケーションの更新を確認するのをやめ、コードで更新タイミングを手動制御することにします(発行画面で言うと「更新...」ボタンから「アプリケーションの更新を確認する」のチェックを外す)。
ここは通常の手動更新なので、特に変わったことはしないです。 ApplicationDeployment.CurrentDeployment で現在の ApplicationDeployment を取得して、CheckForUpdate() で更新チェック、Update() でアップデートします。Google Chromeみたいに気づいたときには更新されているのがいい場合は UpdateAsync() ですかね。
if (ApplicationDeployment.IsNetworkDeployed) { try { var appDeploy = ApplicationDeployment.CurrentDeployment; if (appDeploy.CheckForUpdate()) { Logger.Info("アップデートが検出されました。"); appDeploy.UpdateAsync(); } else { Logger.Info("このアプリケーションは最新版です"); } } catch (Exception ex) { Logger.Error(ex); } } else { Logger.Info("このアプリケーションはネットワーク経由での更新ができません。"); }
で、このままだと、当然プロキシ認証には失敗します。
ネットワークに手を入れます。まずカスタムの WebProxy を作ります。
public class CustomWebProxy : IWebProxy { private WebProxy _orginalProxy; public CustomWebProxy(string server) { _orginalProxy = new WebProxy(server); _orginalProxy.UseDefaultCredentials = false; } public CustomWebProxy(string serverName, int port) { _orginalProxy = new WebProxy(serverName, port); _orginalProxy.UseDefaultCredentials = false; } public void SetCredentials(ICredentials credentials) { _orginalProxy.Credentials = credentials; } public ICredentials Credentials { get { return _orginalProxy.Credentials; } set { } //ここで外部からのセットを無視する } public Uri GetProxy(Uri destination) { return _orginalProxy.GetProxy(destination); } public bool IsBypassed(Uri host) { return _orginalProxy.IsBypassed(host); } }
情報元のブログによれば、ClickOnce はせっかく設定した Credentials をなぜかデフォルトで上書きしてから通信を行っているようです(なんでそんなことしてるのだろう?)。なので、ここではCredentials のSetterプロパティを空振りさせます。かわりに、SetCredentialsというメソッド経由で設定するようにします。
あとはこんなのでOK。
var proxy = new CustomWebProxy("localohost", 8080); proxy.SetCredentials(new NetworkCredential("user", "password")); WebRequest.DefaultWebProxy = proxy;
これで、このアプリケーションから出るリクエストはすべて認証を経由します(WCFで通信を行っている場合は、それらもすべてプロキシ認証されます)。そんなわけで、ClickOnceの手動アップデートはプロキシを乗り越えられるようになりました。ただ、一回目のインストールだけは当然できないので、CDかイメージからのインストールを行って、更新URLを設定しておく必要があります。それはそれで面倒なんですが、更新時にプロキシ認証を越えられるだけでも使えるケースはあると思います。 すいません、これはダメでした。次の記事を参照してください。