예제 #1
0
        public void IsLocalTests()
        {
            var p1 = new ReAttachTarget(0, @"c:\process1.exe", @"domain\username");
            var p2 = new ReAttachTarget(0, @"c:\process2.exe", @"domain\username", "server");

            Assert.IsTrue(p1.IsLocal);
            Assert.IsFalse(p2.IsLocal);
        }
예제 #2
0
 public ReAttachDialog(IReAttachPackage package, ReAttachTarget target)
 {
     InitializeComponent();
     _package = package;
     _target = target;
     ProcessName.Text = string.Format("{0} ({1})", target.ProcessName, target.ProcessUser);
     Dots.Text = "";
     _timer.Tick += TimerOnTick;
     _timer.Interval = new TimeSpan(0, 0, 1);
     _timer.Start();
 }
예제 #3
0
        public void StringFormattingTests()
        {
            var p1 = new ReAttachTarget(0, @"c:\process1.exe", @"domain\username");
            var p2 = new ReAttachTarget(0, @"c:\process2.exe", @"domain\username", "servername");
            Assert.IsTrue(p1.ToString().Contains("process1.exe"), "Formatted string doesn't contain process name.");
            Assert.IsTrue(p1.ToString().Contains(@"domain\username"), "Formatted string doesn't contain username.");

            Assert.IsTrue(p2.ToString().Contains("process2.exe"), "Formatted string doesn't contain process name.");
            Assert.IsTrue(p2.ToString().Contains(@"domain\username"), "Formatted string doesn't contain username.");
            Assert.IsTrue(p2.ToString().Contains("servername"), "Formatted string doesn't contain servername.");
        }
예제 #4
0
        public void EqualityTest()
        {
            var p1 = new ReAttachTarget(0, @"c:\cmd.exe", @"domain\username");
            var p2 = new ReAttachTarget(0, @"c:\CmD.eXe", @"DOMAIn\USeRNAmE");
            Assert.AreEqual(p1, p2);
            Assert.AreEqual(p1.GetHashCode(), p2.GetHashCode());

            var p3 = new ReAttachTarget(1, @"c:\cmd.exe", @"domain\username");
            var p4 = new ReAttachTarget(2, @"c:\CmD.eXe", @"DOMAIn\USeRNAmE");
            Assert.AreEqual(p3, p4);
            Assert.AreEqual(p3.GetHashCode(), p4.GetHashCode());
            Assert.IsTrue(p3.Equals(p4));
        }
예제 #5
0
        public void InequalityTest()
        {
            var p1 = new ReAttachTarget(0, @"c:\cmd.exe", @"domain\username");
            var p2 = new ReAttachTarget(0, @"c:\calc.exe", @"domain\username");
            Assert.AreNotEqual(p1, p2);

            var p3 = new ReAttachTarget(0, @"c:\cmd.exe", @"domain\username1");
            var p4 = new ReAttachTarget(0, @"c:\cmd.exe", @"domain\username2");
            Assert.AreNotEqual(p3, p4);

            Assert.AreNotEqual(null, p1);
            Assert.AreNotEqual(null, p2);
            Assert.AreNotEqual(p3, null);
            Assert.AreNotEqual(p4, null);
            Assert.IsFalse(p3.Equals(null));
        }
예제 #6
0
        public ReAttachTarget GetTargetFromProcess(IDebugProcess2 debugProcess)
        {
            var process = (IDebugProcess3)debugProcess;
            var pid = process.GetProcessId();
            var target = _package.History.Items.Find(pid);
            if (target != null)
                return target;

            var serverName = "";
            IDebugCoreServer2 server;
            if (debugProcess.GetServer(out server) == VSConstants.S_OK)
            {
                var server3 = server as IDebugCoreServer3;
                var tmp = "";
                if (server3 != null && server3.QueryIsLocal() == VSConstants.S_FALSE &&
                    server3.GetServerFriendlyName(out tmp) == VSConstants.S_OK)
                {
                    serverName = tmp;
                }
            }

            var user = GetProcessUsername(pid);
            var path = process.GetFilename();
            target = new ReAttachTarget(pid, path, user, serverName);

            var rawEngines = new GUID_ARRAY[1];

            if (process.GetEngineFilter(rawEngines) == VSConstants.S_OK && rawEngines[0].dwCount > 0)
            {
                var pointer = rawEngines[0].Members;
                var engineCount = rawEngines[0].dwCount;
                for (var i = 0; i < engineCount; i++)
                {
                    var engineId = (Guid)Marshal.PtrToStructure(pointer + (i * 16), typeof(Guid));
                    target.Engines.Add(engineId);
                }
            }
            return target;
        }
예제 #7
0
        public bool ReAttach(ReAttachTarget target)
        {
            if (target == null)
                return false;
            List<Process3> candidates;
            if (!target.IsLocal)
            {
                var transport = _dteDebugger.Transports.Item("Default");
                var processes = _dteDebugger.GetProcesses(transport, target.ServerName).OfType<Process3>();
                candidates = processes.Where(p => p.Name == target.ProcessPath).ToList();
            }
            else
            {
                var processes = _dteDebugger.LocalProcesses.OfType<Process3>();
                candidates = processes.Where(p =>
                    p.Name == target.ProcessPath &&
                    p.UserName == target.ProcessUser).ToList();

                if (!candidates.Any()) // Do matching on processes running in exclusive mode.
                {
                    candidates = processes.Where(p =>
                        p.Name == target.ProcessName &&
                        string.IsNullOrEmpty(p.UserName)).ToList();
                }
            }

            if (!candidates.Any())
                return false;

            Process3 process = null; // First try to use the pid.
            if (target.ProcessId > 0)
                process = candidates.FirstOrDefault(p => p.ProcessID == target.ProcessId);

            // If we don't have an exact match, just go for the highest PID matching.
            if (process == null)
            {
                var maxPid = candidates.Max(p => p.ProcessID);
                process = candidates.FirstOrDefault(p => p.ProcessID == maxPid);
            }

            if (process == null)
                return false;

            try
            {
                if (target.Engines != null && target.Engines.Any())
                {
                    var engines = target.Engines.Where(e => _engines.ContainsKey(e)).Select(e => _engines[e]).ToArray();
                    process.Attach2(engines);
                }
                else
                {
                    process.Attach();
                }
                return true;
            }
            catch (COMException e)
            {
                // It's either this or returning this HRESULT to shell with Shell.ReportError method, shows UAC box btw.
                const int E_ELEVATION_REQUIRED = unchecked((int)0x800702E4);
                Marshal.ThrowExceptionForHR(E_ELEVATION_REQUIRED);
                return false;
            }
            catch (Exception e)
            {
                _package.Reporter.ReportError("Unable to ReAttach to process {0} ({1}) based on target {2}. Message: {3}.",
                    process.Name, process.ProcessID, target, e.Message);
            }
            return false;
        }
예제 #8
0
 public void InvalidPathTest()
 {
     var p1 = new ReAttachTarget(0, @"c:\cmd.exe" + Path.GetInvalidPathChars()[0], @"domain\username1");
     Assert.AreEqual(p1.ProcessName, p1.ProcessPath);
 }