コード例 #1
0
        private void Deploy(DebugPort port)
        {
            Debug.Assert(port != null && !port.IsLocalPort);

            VsPackage.MessageCentre.InternalErrorMsg(DiagnosticStrings.StartDeployAssemblies);

            CorDebugProcess process      = null;
            bool            fDeviceFound = false;

            VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.StartingDeviceDeployment);

            for (int retries = 0; retries < 60; retries++)
            {
                VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.Iteration, retries));

                try
                {
                    process = GetDeviceProcess();

                    if (process != null)
                    {
                        switch (port.PortFilter)
                        {
                        case PortFilter.Serial:
                        case PortFilter.Usb:
                        case PortFilter.TcpIp:
                            //test the connection.  This doesn't tell you if the connection will fail during the AttachToEngine,
                            //but it's a pretty good guess.
                            VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.OpeningPort, process.PortDefinition.Port));
                            fDeviceFound = process.PortDefinition.TryToOpen();
                            if (!fDeviceFound)
                            {
                                VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.PortNotFound, process.PortDefinition.Port));
                            }
                            break;

                        default:
                            SetDeployFailure(string.Format("Device {0} has an unsupported/unexpected port type", this.DeployDeviceDescription));
                            return;
                        }

                        if (fDeviceFound)
                        {
                            break;
                        }
                    }
                }
                catch (IOException)
                {
                }

                Thread.Sleep(500);
            }

            if (!fDeviceFound || process == null)
            {
                SetDeployFailure(string.Format("Device not found or cannot be opened - {0}", this.DeployDeviceDescription));
                return;
            }

            VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.AttachingEngine);

            Engine engine = process.AttachToEngine();

            if (engine == null)
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.CannotAttachEngine);
                SetDeployFailure(string.Format(DiagnosticStrings.UnableToCommunicate, this.DeployDeviceDescription));
                return;
            }

            VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.EngineAttached);

            try
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.QueryingDeviceAssemblies);

                ArrayList assemblies       = new ArrayList();
                Hashtable systemAssemblies = new Hashtable();
                //Ensure Assemblies are loaded
                if (process.IsDeviceInInitializeState())
                {
                    engine.ResumeExecution();
                    Thread.Sleep(200);

                    while (process.IsDeviceInInitializeState())
                    {
                        VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.WaitingInitialize);

                        //need to break out of this or timeout or something?
                        Thread.Sleep(200);
                    }
                }

                WireProtocol.Commands.Debugging_Resolve_Assembly[] assms = engine.ResolveAllAssemblies();

                // find out which are the system assemblies
                // we will insert each system assemblies in a hash table where the value will be the assembly version
                foreach (Debugging_Resolve_Assembly resolvedAssembly in assms)
                {
                    VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.FoundAssembly, resolvedAssembly.m_reply.Name, resolvedAssembly.m_reply.m_version.ToString()));
                    if ((resolvedAssembly.m_reply.m_flags & Debugging_Resolve_Assembly.Reply.c_Deployed) == 0)
                    {
                        systemAssemblies[resolvedAssembly.m_reply.Name.ToLower()] = resolvedAssembly.m_reply.m_version;
                    }
                }

                string[] pes  = m_project.GetDependencies(true, true, engine.IsTargetBigEndian);
                string[] dlls = m_project.GetDependencies(true, false, engine.IsTargetBigEndian);

                Debug.Assert(pes.Length == dlls.Length);

                // now we will re-deploy all system assemblies
                for (int i = 0; i < pes.Length; ++i)
                {
                    string assemblyPath = pes[i];
                    string dllPath      = dlls[i];

                    //is this a system assembly?
                    string fileName          = Path.ChangeExtension(Path.GetFileName(assemblyPath), null).ToLower();
                    bool   fDeployNewVersion = true;

                    if (systemAssemblies.ContainsKey(fileName))
                    {
                        // get the version of the assembly on the device
                        Debugging_Resolve_Assembly.Version deviceVer = (WireProtocol.Commands.Debugging_Resolve_Assembly.Version)systemAssemblies[fileName];

                        // get the version of the assembly of the project
                        // We need to load the bytes for the assembly because other Load methods can override the path
                        // with gac or recently used paths.  This is the only way we control the exact assembly that is loaded.
                        byte[] asmData = null;

                        using (FileStream sr = new FileStream(dllPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            asmData = new byte[sr.Length];
                            sr.Read(asmData, 0, (int)sr.Length);
                        }

                        System.Reflection.Assembly assm = Assembly.Load(asmData); Version deployVer = assm.GetName().Version;

                        // compare versions strictly, and deploy whatever assembly does not match the version on the device
                        if (VsProject.TargetFrameworkExactMatch(deviceVer, deployVer))
                        {
                            fDeployNewVersion = false;
                        }
                        else
                        {
                            ////////////////////////////////////////////////
                            //            !!! SPECIAL CASE !!!            //
                            //                                            //
                            // MSCORLIB cannot be deployed more than once //
                            ////////////////////////////////////////////////

                            if (assm.GetName().Name.ToLower().Contains("mscorlib"))
                            {
                                string message = string.Format("Cannot deploy the base assembly '{9}', or any of his satellite assemblies, to device - {0} twice. Assembly '{9}' on the device has version {1}.{2}.{3}.{4}, while the program is trying to deploy version {5}.{6}.{7}.{8} ", this.DeployDeviceDescription, deviceVer.iMajorVersion, deviceVer.iMinorVersion, deviceVer.iBuildNumber, deviceVer.iRevisionNumber, deployVer.Major, deployVer.Minor, deployVer.Build, deployVer.Revision, assm.GetName().Name);
                                VsPackage.MessageCentre.DeploymentMsg(message);
                                SetDeployFailure(message);
                                return;
                            }
                        }
                    }
                    // append the assembly whose version does not match, or that still is not on the device, to the blob to deploy
                    if (fDeployNewVersion)
                    {
                        using (FileStream fs = File.Open(assemblyPath, FileMode.Open, FileAccess.Read))
                        {
                            VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.AddingPEtoBundle, assemblyPath));
                            long   length = (fs.Length + 3) / 4 * 4;
                            byte[] buf    = new byte[length];

                            fs.Read(buf, 0, (int)fs.Length);
                            assemblies.Add(buf);
                        }
                    }
                }

                VsPackage.MessageCentre.DeploymentMsg("Attempting deployment...");

                if (!engine.Deployment_Execute(assemblies, false, VsPackage.MessageCentre.DeploymentMsg))
                {
                    VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.DeployFailed);
                    SetDeployFailure();
                    return;
                }
            }
            finally
            {
                process.DetachFromEngine();
            }
        }