2014-12-31 13 views
5

Tôi đang cố gắng xác định múi giờ hiện tại cho hệ thống Windows. Đoạn mã sau là (lỏng lẻo) dựa trên câu trả lời bằng @MattJohnson về chủ đề này: Getting local timezone identifier when OS display language is non-englishHKLM SYSTEM CurrentControlSet Control TimeZoneInformation TimeZoneKeyName bị hỏng?

using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(
            @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation")) 
    { 
     if (registryKey != null) 
     { 
      string windowsTimeZoneId = registryKey.GetValue("TimeZoneKeyName") as string; 
      if (string.IsNullOrEmpty(windowsTimeZoneId)) 
      windowsTimeZoneId = registryKey.GetValue("StandardName") as string; 
      if (!string.IsNullOrEmpty(windowsTimeZoneId)) 
      { 
      int i = windowsTimeZoneId.IndexOf('\0'); 
      if (i != -1) 
       windowsTimeZoneId = windowsTimeZoneId.Remove(i); 
      return ConvertFromWindowsId(windowsTimeZoneId); 
      } 
     } 
    } 

Nếu tôi đặt một breakpoint trên dòng đầu tiên "if (string.IsNullOrEmpty (windowsTimeZoneId))", thì đây là những gì tôi thấy trong trình gỡ lỗi Visual Studio:

enter image description here

Điều gì đang xảy ra ở đây? RegistryKey.GetValue() là trả về một chuỗi đóng hộp, nhưng tại sao nó không phát hiện hai byte 00 byte và chấm dứt chuỗi đó?

Cho đến nay tôi đã thử nghiệm điều này trên hai máy tính cá nhân của mình. Điều này là từ một trong đó chạy Windows 7 64-bit. Một cái khác, chạy Windows 7 32-bit, là giống nhau ngoại trừ việc nó nói rằng độ dài của chuỗi được trả về là 128 ký tự thay vì 127.

Khi nhìn vào mục đăng ký với regedit.exe có vẻ ổn, chỉ hiển thị "Romance Standard Time".

Một chút Googling đã bật câu hỏi này https://social.msdn.microsoft.com/Forums/sqlserver/en-US/eca7ad76-c910-46be-8fb9-876c7cde5c69/registry-read-time-zone-info-differ-when-code-build-on-40-framework-on-host-system-win-7-64-bit?forum=csharpgeneral Nếu không, tôi không thể tìm thấy bất kỳ điều gì.

Chương trình đang được xây dựng với Visual Studio 2012 và nhắm mục tiêu .Net 2.0. Như bạn có thể thấy, tôi đã thêm mã để đưa kết quả "bị hỏng" này vào tài khoản, nhưng tôi vẫn đánh giá cao nếu ai đó có thể giải thích cho tôi điều gì đang xảy ra ở đây và thậm chí có thể làm cách nào để tránh toàn bộ vấn đề.

EDIT:

Chương trình đang được xây dựng với Visual Studio 2012, và nhắm mục tiêu Net 2.0.

Hmm, cốt truyện dày hơn. Tuyên bố đó không hoàn toàn chính xác. Gốc của mã được hiển thị ở trên là trong một thư viện lắp ráp được xây dựng để nhắm mục tiêu .Net 2.0, nhưng nó đã được gọi từ một chương trình nhắm mục tiêu .Net 4.0. Bây giờ tôi đã cố gắng gọi nó từ một chương trình mà mục tiêu. Net 2.0, và không có vấn đề, RegistryKey.GetValue() chỉ đơn giản là trả về "Romance Standard Time". Vì vậy, nó xuất hiện rằng nó không có cái gì để làm với .Net Framework 4.0, như ngụ ý bởi việc đăng trên MSDN.

EDIT 2 - bắt đầu nghĩ rằng đây là "bình thường"

Đây là một chủ đề off-bit cho SO, nhưng tôi muốn đánh giá cao nếu ai đó sẽ có một cái nhìn tại đăng tải liên quan của tôi qua tại superuser. com, vì tôi không nhận được sự hài lòng ngay lập tức ở đó, và tôi muốn giải quyết vấn đề này vì vậy tôi biết liệu tôi có nên vẫn hoảng sợ hay không. Cảm ơn.

https://superuser.com/questions/859031/possible-malware-modification-of-windows-registry-entry

+0

Chi tiết rất thú vị. Cũng lưu ý rằng Giờ chuẩn lãng mạn áp dụng ở châu Âu - không phải Mexico. Vì vậy, không có cách nào điều này được thực hiện cố ý, vì các giá trị không liên quan trong cùng một chuỗi. –

+0

@Matt: Tôi nghi ngờ dữ liệu dư thừa là ngẫu nhiên, chỉ bất cứ điều gì xảy ra trong bộ nhớ khi bộ đệm được cấp phát. Hình như Windows chính nó đang làm điều này; nếu tôi xóa nội dung thừa, sau đó thay đổi múi giờ, nó sẽ xuất hiện trở lại. Có vẻ giống như cùng một dữ liệu mỗi lần, nhưng tôi chưa thử khởi động lại máy để xem liệu nó có làm cho nó trông khác đi không. –

Trả lời

2

Khi một chuỗi hoặc giá trị đa chuỗi được thiết lập trong registry, Windows không kiểm tra ngữ nghĩa; nó đơn giản lưu trữ bất kỳ nội dung nhị phân nào được cung cấp, với độ dài được chỉ định bởi lập trình viên. Điều này có nghĩa là một chuỗi có thể được kết thúc sớm bằng null, hoặc ngược lại, không được kết thúc bằng null. (Điều này không có tác động an ninh, bằng cách này: trong khi tôi không nghĩ rằng chấm dứt null sớm có khả năng đặt ra một nguy cơ, mã nguồn gốc không xử lý các trường hợp chuỗi không phải là null chấm dứt có thể.)

Theo Hans (trong câu trả lời đã xóa) của phiên bản .NET trước 4.x sẽ bỏ qua dữ liệu bổ sung nếu chuỗi được kết thúc sớm null, trong khi 4.x bao gồm nó. Vì vậy, đó là lý do tại sao bạn chỉ nhận thấy sự cố khi bạn bắt đầu sử dụng 4.x.

Đối với lý do tại sao giá trị cụ thể này là sớm chấm dứt null, dường như là bất cẩn trên phần của Microsoft. Nếu bạn xóa dữ liệu bổ sung, sau đó thay đổi múi giờ, dữ liệu bổ sung sẽ xuất hiện trở lại. Vì vậy, nó xuất hiện để được Windows chính nó đang làm điều này. Các dữ liệu trông ngẫu nhiên với tôi, vì vậy tôi không tin rằng đó là cố ý. Trong thực tế, điều này có thể tạo thành một lỗ hổng tiếp xúc dữ liệu, mặc dù có lẽ không có tác động thực tế.

Tôi đề nghị bạn tìm kiếm một chuỗi rỗng và cắt ngắn chuỗi nếu cần. Có thể có các tình huống trong đó không có trường hợp, ví dụ: nếu mục nhập đã được sửa đổi bởi mã của bên thứ ba hoặc nếu MS cuối cùng phát hành bản cập nhật và khắc phục sự cố hoặc, tất nhiên, nếu bạn đang chạy. NET 2.x. Vì vậy, bạn sẽ cần phải xử lý cả hai trường hợp.

(Nếu có thời gian, khi tôi quay lại làm việc vào tuần tới, tôi sẽ cài đặt một bản sao Windows sạch trên máy ảo và xác nhận rằng vấn đề tồn tại với hoàn toàn không có phần mềm của bên thứ ba. sẽ xem xét báo cáo nó - Tôi nghi ngờ MS sẽ phát hành một bản vá, nhưng nó có thể được sửa trong một phiên bản tương lai của Windows.)

+0

Cảm ơn bạn rất nhiều vì đã kiểm tra điều này và giải thích tốt cho bạn. Bây giờ tôi có thể ngủ dễ dàng một lần nữa. (Câu trả lời của Hans khiến tôi thực sự thất vọng, và tôi đang trên bờ vực liên lạc với một khách hàng mới và cảnh báo họ rằng tôi có thể đã vô tình lây nhiễm khoảng 300 máy tính của họ bằng một loại virus không thể phát hiện được. Điều đó đã khiến tôi rất nổi tiếng với họ). – RenniePet