|
|
using System; using System.Text; using System.Net; using System.IO; using System.Text.RegularExpressions; using System.Runtime.Remoting; using System.Globalization; using System.Security; using System.Security.Policy; using System.Security.Permissions; using System.Collections; using System.Runtime.InteropServices; using System.Reflection; using System.Configuration.Assemblies; using System.Threading; using System.Xml; using System.Xml.XPath;
namespace Microsoft.Fusion.ADF { //----------------------------------------------------------
// ApplicationMoniker
//----------------------------------------------------------
public class ApplicationMoniker : IWebRequestCreate { ManualResetEvent _event; int _totalRead; const int BUFFER_SIZE = 0x4000; Uri _manifestUri; Uri _appBase; ApplicationManifestImport _applicationManifestImport; AssemblyIdentity _assemblyIdentity; string _manifestFileName; string _appStorePath;
Progress _progress; Hashtable _jobTable; Queue _jobQueue;
bool _bDone; int _totalSize; //----------------------------------------------------------
// ctor
//----------------------------------------------------------
public ApplicationMoniker(string manifestUri, string appBase) { _manifestUri = new Uri(manifestUri); string path = _manifestUri.LocalPath; _manifestFileName = System.IO.Path.GetFileName(path); if (appBase != null) _appBase = new Uri(appBase); else { string appBaseString = manifestUri.Substring(0, manifestUri.Length - _manifestFileName.Length); _appBase = new Uri(appBaseString); }
_applicationManifestImport = new ApplicationManifestImport(_manifestUri);
_assemblyIdentity = _applicationManifestImport.GetAssemblyIdentity();
string appDirName = _assemblyIdentity.GetDirectoryName(); string userprofile = Environment.GetEnvironmentVariable("userprofile");
_appStorePath = userprofile + "\\Local Settings\\My Programs\\__temp__\\" + appDirName;
_progress = new Progress();
_jobTable = new Hashtable(); _jobQueue = new Queue(); _totalRead = 0; _totalSize = 0; }
//----------------------------------------------------------
// ApplicationMoniker
//----------------------------------------------------------
public WebRequest Create(Uri uri) { return ApplicationMonikerRequest.Create(uri, _appBase, _appStorePath); }
//----------------------------------------------------------
// GetApplicationManifestImport
//----------------------------------------------------------
public ApplicationManifestImport GetApplicationManifestImport() { return new ApplicationManifestImport(_manifestUri); }
//----------------------------------------------------------
// AppBase
//----------------------------------------------------------
public string AppBase { get { return _appBase.ToString();} }
//----------------------------------------------------------
// GetAppInfo
//----------------------------------------------------------
public void GetAppInfo(ref int nFiles, ref int nAssemblies) { DependentFileInfo dfi; DependentAssemblyInfo dai;
_applicationManifestImport.ResetIterators();
nFiles = nAssemblies = 0; while ((dfi = _applicationManifestImport.GetNextDependentFileInfo()) != null) { Uri httpSite = new Uri(_appBase, dfi["name"]); nFiles++; _totalSize += GetContentLength(httpSite); }
while ((dai = _applicationManifestImport.GetNextDependentAssemblyInfo()) != null) { Uri httpSite = new Uri(_appBase, dai["codeBase"]); nFiles++; _totalSize += GetContentLength(httpSite); } _applicationManifestImport.ResetIterators(); }
//----------------------------------------------------------
// GetContentLength
//----------------------------------------------------------
public int GetContentLength(Uri uri) { HttpWebRequest webRequest = (HttpWebRequest) WebRequest.CreateDefault(uri); webRequest.Method = "HEAD"; WebResponse wr = webRequest.GetResponse(); return (int) wr.ContentLength; } //----------------------------------------------------------
// DownloadManifestAndDependencies
//----------------------------------------------------------
public void DownloadManifestAndDependencies() { int nTotal = 0, nFiles = 0, nAssemblies = 0;
_bDone = false;
GetAppInfo(ref nFiles, ref nAssemblies); nTotal = nFiles + nAssemblies; _totalSize += GetContentLength(_manifestUri);
_progress.SetRange(0, _totalSize); _progress.SetStatus(0); _progress.SetText("Downloading..."); _progress.Activate(); _progress.Visible = true; System.Windows.Forms.Application.DoEvents();
DoDownload(_manifestUri); while (true) { System.Windows.Forms.Application.DoEvents(); if (_bDone == true) break; } _progress.Visible = false; }
//----------------------------------------------------------
// DoDownload
//----------------------------------------------------------
void DoDownload(Uri appManifestUri) { ApplicationMonikerRequest request = (ApplicationMonikerRequest) ApplicationMonikerRequest.Create(appManifestUri, _appBase, _appStorePath); request.type = FileType.ApplicationManifest;
_jobTable[appManifestUri] = request;
RequestState rs = new RequestState(); rs.Request = request; IAsyncResult r = (IAsyncResult) request.BeginGetResponse( new AsyncCallback(RespCallback), rs);
}
//----------------------------------------------------------
// RespCallback
//----------------------------------------------------------
void RespCallback(IAsyncResult ar) { RequestState rs = (RequestState) ar.AsyncState;
ApplicationMonikerRequest req = rs.Request;
ApplicationMonikerResponse resp = (ApplicationMonikerResponse) req.EndGetResponse(ar);
ApplicationMonikerStream ResponseStream = (ApplicationMonikerStream) resp.GetResponseStream();
rs.ResponseStream = ResponseStream;
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs); }
//----------------------------------------------------------
// ReadCallback
//----------------------------------------------------------
void ReadCallBack(IAsyncResult asyncResult) { RequestState rs = (RequestState) asyncResult.AsyncState;
ApplicationMonikerStream responseStream = rs.ResponseStream;
int read = responseStream.EndRead( asyncResult ); if (read > 0) { _totalRead += read; IAsyncResult ar = responseStream.BeginRead( rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs); } else { _progress.SetStatus((int) _totalRead); _progress.SetText("Downloading: " + responseStream.path); _progress.SetTotal("Total: " + _totalRead.ToString() + "/" + _totalSize.ToString() + " bytes read");
responseStream.Close(); if ((rs.Request.type == FileType.ApplicationManifest) || (rs.Request.type == FileType.ComponentManifest)) { IAssemblyManifestImport assemblyManifestImport;
Uri cachePath = responseStream.GetCachePath();
if (rs.Request.type == FileType.ApplicationManifest) assemblyManifestImport = new ApplicationManifestImport(cachePath); else // this is a drag - we can't even do this - the loadfrom will fail if modules not present.
// soln for now is to ignore component constituents (don't enqueue them)
// assemblyManifestImport = new ComponentManifestImport(cachePath);
goto done; ApplicationMonikerRequest newRequest; while ((newRequest = GetNextRequest(assemblyManifestImport)) != null) { if (_jobTable[newRequest.RequestUri] == null) { if (newRequest.CachedCopyExists() != true) { _jobQueue.Enqueue(newRequest); _jobTable[newRequest.RequestUri] = newRequest; } else { _totalRead += (int) newRequest.GetCacheFileSize(); _progress.SetStatus((int) _totalRead); newRequest.Dispose(); } } } } done:
if (_jobQueue.Count == 0) _bDone = true; else { ApplicationMonikerRequest nextRequest = (ApplicationMonikerRequest) _jobQueue.Dequeue();
RequestState rsnext = new RequestState(); rsnext.Request = nextRequest;
IAsyncResult r = (IAsyncResult) nextRequest.BeginGetResponse( new AsyncCallback(RespCallback), rsnext); } } return; }
//----------------------------------------------------------
// PurgeFiles
//----------------------------------------------------------
public void PurgeFiles() { DirectoryInfo di = new DirectoryInfo(_appStorePath); di.Delete(true); } //----------------------------------------------------------
// GetNextRequest
//----------------------------------------------------------
public ApplicationMonikerRequest GetNextRequest(IAssemblyManifestImport ami) { FileType type; Uri codebase;
DependentFileInfo dfi; DependentAssemblyInfo dai;
// we can't do components for now.
if (ami.GetFileType() == FileType.ComponentManifest) return null;
dfi = ami.GetNextDependentFileInfo(); if (dfi != null) { codebase = new Uri(_appBase, dfi["name"]); type =FileType.RawFile; } else { // Don't follow component dependencies.
// if (ami.GetFileType() == FileType.ComponentManifest)
// return null;
dai = ami.GetNextDependentAssemblyInfo(); if (dai != null) { codebase = new Uri(_appBase, dai["codeBase"]); type = FileType.ComponentManifest; } else { codebase = null; type = FileType.Unknown; } } if (codebase == null) return null;
ApplicationMonikerRequest request = (ApplicationMonikerRequest) ApplicationMonikerRequest.Create(codebase, _appBase, _appStorePath); request.type = type; return request; } }
//----------------------------------------------------------
// RequestState
//----------------------------------------------------------
class RequestState { const int BufferSize = 0x4000; public byte[] BufferRead; public ApplicationMonikerRequest Request; public ApplicationMonikerStream ResponseStream; //----------------------------------------------------------
// ctor
//----------------------------------------------------------
public RequestState() { BufferRead = new byte[BufferSize]; Request = null; ResponseStream = null; } }
}
|