2016-02-23 24 views
1

我使用的是下面一行到我WTS_PROCESS_INFO對象的ProcessName財產轉換爲字符串:不可靠元帥轉換時詮釋爲String根據框架

string name = Marshal.PtrToStringUni(processInfos[I].processName)

這似乎是相當可靠的,所有的過程名稱已成功轉換。

然而,如果我使這個相同呼叫傳遞WTS_PROCESS_INFO到另一個類和方法,每次嘗試在從第一次嘗試轉換爲字符串結果""開之後。

這僅只是利用.NET-3.5時發生,但似乎.NET-4.0

例做工精細:

工作 - 每名經過整個列表之前轉換爲正確的字符串。

public static List<Proc> WTSEnumerateProcesses(string servername) 
    { 
     IntPtr pProcessInfo = IntPtr.Zero; 
     int processCount = 0; 
     var hServer = OpenServer(servername); 

     if (!Native.WTSEnumerateProcesses(hServer, 0, 1, ref pProcessInfo, ref processCount)) 
      return null; 

     IntPtr pMemory = pProcessInfo; 
     WTS_PROCESS_INFO[] processInfos = new WTS_PROCESS_INFO[processCount]; 
     for (int i = 0; i < processCount; i++) 
     { 
      processInfos[i] = (WTS_PROCESS_INFO)Marshal.PtrToStructure(pProcessInfo, typeof(WTS_PROCESS_INFO)); 
      pProcessInfo = (IntPtr)((int)pProcessInfo + Marshal.SizeOf(processInfos[i])); 
     } 

     List<Proc> asd = new List<Proc>(); 
     foreach (var item in processInfos) 
     { 
      if (item.SessionID == 5) 
      { 
       string procname = Marshal.PtrToStringUni(item.ProcessName); 
       var proc = new Proc(servername, 5, item.SessionID, procname); 
       asd.Add(proc); 
      } 
     } 

     Native.WTSFreeMemory(pMemory); 
     return asd; 
    } 

不工作 - 這發生(從第一個開)使WTS_PROCESS_INFO出去了結果在空字符串之後的轉換。

public static WTS_PROCESS_INFO[] WTSEnumerateProcesses(string servername) 
    { 
     IntPtr pProcessInfo = IntPtr.Zero; 
     int processCount = 0; 
     var hServer = OpenServer(servername); 

     if (!Native.WTSEnumerateProcesses(hServer, 0, 1, ref pProcessInfo, ref processCount)) 
      return null; 

     IntPtr pMemory = pProcessInfo; 
     WTS_PROCESS_INFO[] processInfos = new WTS_PROCESS_INFO[processCount]; 
     for (int i = 0; i < processCount; i++) 
     { 
      processInfos[i] = (WTS_PROCESS_INFO)Marshal.PtrToStructure(pProcessInfo, typeof(WTS_PROCESS_INFO)); 
      pProcessInfo = (IntPtr)((int)pProcessInfo + Marshal.SizeOf(processInfos[i])); 
     } 

     Native.WTSFreeMemory(pMemory); 
     return processInfos; 
    } 

任何人都可以解釋爲什麼會發生這種情況嗎?

回答

2

因爲您打電話Native.WTSFreeMemory(pMemory);釋放與字符串關聯的內存。這個調用釋放了pMemory這是一個數組WTS_PROCESS_INFO和從各種pProcessName指出的內存。所以解決的辦法是複製某些地方的字符串之前打電話Native.WTSFreeMemory(pMemory);

+0

啊,謝謝你xanatos!你會說在這裏稱此爲好習慣,還是應該稍後做一些有用的工作並釋放內存? – Bassie

+1

@Bassie你必須在方法中釋放它,因爲只有在你有'pMemory'指針的方法中。我的建議是創建一個'MyWtsProcessInfo'(有一個'string processName'),將數據從'processInfos [i]'複製到這個新類並釋放'pMemory'。 – xanatos