Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在启动远程桌面客户端。无法控制PID压井。启动后PID发生变化…WTF?_C#_Process_C# 4.0_Remote Desktop - Fatal编程技术网

C# 正在启动远程桌面客户端。无法控制PID压井。启动后PID发生变化…WTF?

C# 正在启动远程桌面客户端。无法控制PID压井。启动后PID发生变化…WTF?,c#,process,c#-4.0,remote-desktop,C#,Process,C# 4.0,Remote Desktop,我正在编写一个程序(C#Windows窗体的Visual Studio 2010),它跟踪远程桌面客户端的多个实例(mstsc.exe-使用Windows 7版本进行测试)。我一直在尝试启动此程序,并用以下代码获取其PID: Process mstsc = Process.Start(mstscLocation, mstscConString); int mstscProcessId = mstsc.Id; DataRow row = openConn.NewRow(); row["RDP ID

我正在编写一个程序(C#Windows窗体的Visual Studio 2010),它跟踪远程桌面客户端的多个实例(mstsc.exe-使用Windows 7版本进行测试)。我一直在尝试启动此程序,并用以下代码获取其PID:

Process mstsc = Process.Start(mstscLocation, mstscConString);
int mstscProcessId = mstsc.Id;
DataRow row = openConn.NewRow();
row["RDP ID"] = mstscID;
openConn.Rows.Add(row);
这将启动客户机并返回它应该返回的ID。问题是,如果我尝试用以下代码终止PID,它将失败:

int rdpID = Convert.ToInt32(dgvOpenConnections.Rows[selectedIndex].Cells["RDP ID"].Value.ToString());

try
{
    // kill off mstsc
    Process mstsc = Process.GetProcessById(rdpID);
    mstsc.Kill();
}
我已经验证了从Process.Start记录的PID与从DataGridView(dgvOpenConnections)检索并放入rpdID的PID相同(由于原始PID不再存在,try失败并点击catch)。此外,在启动一个MSTSC.EXE实例后,我在命令提示符下发出了一个“tasklist”,可以验证它是否更改了PID(在本测试中,C#录制了4288,但tasklist显示它作为8172运行)

我无法杀死所有MSTSC进程,因为我试图控制多个进程。是否有办法追踪MSTSC使用的第二个PID?我猜它要么启动第二个进程并摆脱第一个进程,要么这是一个子进程(尽管启动后返回的PID不再存在)


在C#中,我如何确保拥有正确的进程ID,以便以后监视或终止远程桌面客户端的特定实例?

我使用process Explorer尝试了您的示例,但没有看到正在创建的第二个或子进程。从开始到结束,远程桌面进程都是一个相同的进程,创建后,我能够使用我在开始时看到的相同PID终止该进程。

我使用Process Explorer尝试了您的示例,但没有看到正在创建的第二个或子进程。远程桌面进程自始至终都是一个相同的进程,创建后,我能够使用我在开始时看到的相同PID终止该进程。

如果您试图在64位Windows中从32位应用程序运行mstsc,就会发生这种情况。

(来源:)

64位Windows上有两个版本的mstsc:

  • c:\windows\system32\mstsc.exe
    是一个64位的版本
  • c:\windows\syswow64\mstsc.exe
    或多或少是一个“重定向”,它将从应用程序以外的进程打开
    c:\windows\system32\mstsc.exe
  • 我也有同样的问题。我的应用程序启动了mstsc,进程立即退出,mstsc以不同的父进程和不同的PID重新出现

    这是因为64位Windows使用文件系统重定向将对64位
    c:\Windows\system32
    可执行文件的调用重定向到
    c:\Windows\syswow64

    有两种解决方案:

  • 将应用程序重新编译为64位。然后,您的应用程序也将使用64位mstsc
  • 禁用文件系统重定向(请参阅),并从32位应用程序访问64位mstsc
  • 我只试过重新编译,结果成功了。:-)

    编辑: 如果您不希望您的用户使用正确的版本(我们使用ClickOnce部署,因此我们宁愿向每个人发送一个链接),这里有一个解决方法:

    如果要为mstsc使用.RDP文件,只需在文件名中添加一个唯一的标记。mstsc将使用命令行启动,如
    mstsc host\u user\u token.rdp

    现在,在调用
    Process.Start
    之后,执行
    Process.WaitForExit
    ,并执行一个短超时(5s)。如果进程未退出,则您拥有正确的对象

    如果进程确实退出,请执行一个小的轮询循环(100毫秒间隔,5秒超时),检查是否有进程使用您的令牌:

    var timeout = AppSettings.GetIntValue(
                Constants.SettingsKeyProcessFinderTimeout, Constants.ProcessFinderTimeoutDefault);
    int elapsedTime = 0;
    Process process = null;
    while (elapsedTime <= timeout)
    {
        process =
            Process.GetProcessesByName("mstsc").FirstOrDefault(p => p.StartInfo.Arguments.Contains(guid));
        Logger.TraceVerbose(
            string.Format(
                "Elapsed time: {0}; Found process with PID {1}", elapsedTime, process == null ? -1 : process.Id));
        if (process != null)
        {
            break;
        }
    
        Thread.Sleep(SleepInterval);
        elapsedTime += SleepInterval;
    }
    
    var timeout=AppSettings.GetIntValue(
    Constants.SettingsKeyProcessFinderTimeout,Constants.ProcessFinderTimeoutDefault);
    int elapsedTime=0;
    Process=null;
    而(elapsedTime p.StartInfo.Arguments.Contains(guid));
    TraceVerbose(
    字符串格式(
    “运行时间:{0};找到PID为{1}的进程”,elapsedTime,进程==null?-1:process.Id));
    if(进程!=null)
    {
    打破
    }
    睡眠(睡眠间隔);
    elapsedTime+=睡眠时间间隔;
    }
    

    在该循环之后,如果您仍然有
    process==null
    ,则会出现一些错误(找不到进程或根本没有执行过进程)。如果您有一个进程引用,那就是“新的”mstsc进程。

    如果您试图在64位Windows中从32位应用程序运行mstsc,就会发生这种情况。

    (来源:)

    64位Windows上有两个版本的mstsc

  • c:\windows\system32\mstsc.exe
    是一个64位的版本
  • c:\windows\syswow64\mstsc.exe
    或多或少是一个“重定向”,它将从应用程序以外的进程打开
    c:\windows\system32\mstsc.exe
  • 我也有同样的问题。我的应用程序启动了mstsc,进程立即退出,mstsc以不同的父进程和不同的PID重新出现

    这是因为64位Windows使用文件系统重定向将对64位
    c:\Windows\system32
    可执行文件的调用重定向到
    c:\Windows\syswow64

    有两种解决方案:

  • 将应用程序重新编译为64位。然后,您的应用程序也将使用64位mstsc
  • 禁用文件系统重定向(请参阅),并从32位应用程序访问64位mstsc
  • 我只试过重新编译,结果成功了。:-)

    编辑: 如果您不希望您的用户使用正确的版本(我们使用ClickOnce部署,因此我们宁愿向每个人发送一个链接),这里有一个解决方法:

    如果要为mstsc使用.RDP文件,只需在文件名中添加一个唯一的标记。mstsc将