iorikyoID:iorikyo
10794次访问,排名9943好友0人,关注者0
iorikyo的文章
原创 10 篇
翻译 0 篇
转载 1 篇
评论 1 篇
最近评论
BoBo_32:在系统中正好此文章将的内容.

在本地使用"控制台程序"可是实现.

但是将此代码拷贝到winform应用程序,编译可以通过,但是在运行时提示:MissingManifestResourceException异常,请问如何处理呢???

请大虾指点一下啊:)
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 用C#设置系统时间和本地时间收藏

      新一篇: C#关闭应用程序时如何关闭子线程 | 旧一篇: .net中用代码生成界面控件

       

              前些日子在工作中遇到一个在原子交易中用C#设置系统时间的问题,虽是一个小问题,却因为C#本身没有这种函数而耽误了一些时间,C#要设置系统时间必须要调用Win32的API,而其中相关的函数就是SetSystemTime(), GetSystemTimer(), SetLocalTime(), GetLocalTime(), 这似乎是用VC写的函数,在VC++中是可以直接调用的。MSDN上面对这几个函数解释得不是很详细,网上可以找到不少这样的程序,但我个人感觉对这些函数的功能和注意点说得也不够透彻,包括那个所谓经过测试的。这里把自己所用到的一些功能和体会给出来,至少要把SetSystemTIme()和SetLocalTime()这两个函数的区别搞清楚。

      对于这两个函数,其输入参数必须是一个下面这样的结构体,其成员变量类型必须是ushort,成员变量不能改变顺序。

          [StructLayout(LayoutKind.Sequential)]
       public struct SystemTime
       
      {
        
      public ushort wYear;
        
      public ushort wMonth;
        
      public ushort wDayOfWeek;
        
      public ushort wDay;
        
      public ushort wHour;
        
      public ushort wMinute;
        
      public ushort wSecond;
        
      public ushort wMiliseconds;
       }

      调用Win32的API,根据需要选用:

       

       public class Win32
       
      {
        [DllImport(
      "Kernel32.dll")]
        
      public static extern bool SetSystemTime(ref SystemTime sysTime );
        [DllImport(
      "Kernel32.dll")]
        
      public static extern bool SetLocalTime(ref SystemTime sysTime);
        [DllImport(
      "Kernel32.dll")]
        
      public static extern void GetSystemTime(ref SystemTime sysTime);
        [DllImport(
      "Kernel32.dll")]
        
      public static extern void GetLocalTime(ref SystemTime sysTime);
       }

      下面是SetLocalTime的调用,SetLocalTime的功能就是设置本地系统时间。因为我的工作中要用到的是根据XML文件中的节点内容字符串通过解析后来设置系统时间,所以我做了一个通过输入字符串参数设置本地系统时间的函数,其中调用了SetLocalTime()函数。

       

              public static bool SetLocalTimeByStr(string timestr)
              {
                  
      bool flag=false;
                  SystemTime sysTime 
      =new SystemTime();
                  
                  
      string SysTime=timestr.Trim();   //此步骤多余,为方便程序而用直接用timestr即可
                  sysTime.wYear = Convert.ToUInt16(SysTime.Substring(0,4));
                  sysTime.wMonth 
      = Convert.ToUInt16(SysTime.Substring(4,2));
                  sysTime.wDay
      =Convert.ToUInt16(SysTime.Substring(6,2));
                  sysTime.wHour
      =Convert.ToUInt16(SysTime.Substring(8,2));
                  sysTime.wMinute 
      = Convert.ToUInt16(SysTime.Substring(10,2));
                  sysTime.wSecond 
      = Convert.ToUInt16(SysTime.Substring(12,2));
                 
      //注意:
                  
      //结构体的wDayOfWeek属性一般不用赋值,函数会自动计算,写了如果不对应反而会出错
                  
      //wMiliseconds属性默认值为一,可以赋值
                  try
                  {
                      flag
      =Win32.SetLocalTime(ref sysTime);
                  }
                  
      //由于不是C#本身的函数,很多异常无法捕获
                 
      //函数执行成功则返回true,函数执行失败返回false
                 
      //经常不返回异常,不提示错误,但是函数返回false,给查找错误带来了一定的困难
                  catch(Exception ex1)
                  {
                      Console.WriteLine(
      "SetLocalTime函数执行异常"+ex1.Message);
                  }

                  
      return flag;
              }

      如果不是以字符串来赋值,而以int甚至ushort类型数来赋值将会更加简单,不多说了。

      程序执行之后本地系统时间将会如期改变。

      那么SetLocalTime()和SetSystemTime()又有什么区别呢?大家可以把上述函数的“flag=Win32.SetLocalTime(ref sysTime);”部分换成“flag=Win32.SetSystemTime(ref sysTime);”试试,你将会发现这样一个结果:

      执行后系统时间也会改变,但总是比预期的有些偏差,中国的朋友估计都会多出8个小时来。

      这是时区的设置造成的,SetSystemTime()默认设置的为UTC时间,当系统设置时间的时候还会按照时区加上一个偏差。而我们的用的北京时间也就是东八区时间,刚好比UTC多了8个小时。这回了解二者的区别了吧。

              这个偏差是不是可以补回来呢?比如对于北京时间,设置完之后减去8个小时就可以了吗?是这么回事,但是具体做起来要有些麻烦,因为要考虑到天,月甚至年都有可能会造成改变,还要考虑到不同的月份。虽然有了SetLocalTime,再来考虑这个有些多此一举,或者也可以直接从时区的方法上入手,但是我偏偏不服,做了一个这样的方法,只是小试一下,没有自己审核,可能会有bug,给大家参考:

              //从字符串设置系统时间
              public bool SetSysTimeByStr(string timestr)
              
      {
                  
      int temp=0;
                  SystemTime sysTime 
      =new SystemTime();
                  
      //给sysTIme初始赋值
                  Win32.GetSystemTime(ref sysTime);
                  
      string SysTime=timestr;
                  sysTime.wYear 
      = Convert.ToUInt16(SysTime.Substring(0,4));
                  sysTime.wMonth 
      = Convert.ToUInt16(SysTime.Substring(4,2));
                  sysTime.wDay
      =Convert.ToUInt16(SysTime.Substring(6,2));
                  sysTime.wHour
      =Convert.ToUInt16(SysTime.Substring(8,2));

                  
      //为抵消北京时间+8而进行的操作
                  temp=Convert.ToInt16(SysTime.Substring(8,2))-8;
                  
      if(temp<0)
                  
      {
                      sysTime.wHour 
      =Convert.ToUInt16(temp+24);//Convert.ToUInt16(SysTime.Substring(8,2))-Convert.ToInt16(8);
                      sysTime.wDay=Convert.ToUInt16(sysTime.wDay-1);
                      
      if(sysTime.wDay==0)
                      
      {
                          
      if(sysTime.wMonth==5|sysTime.wMonth==7|sysTime.wMonth==8|sysTime.wMonth==10|sysTime.wMonth==12)
                          
      {
                              sysTime.wMonth
      =Convert.ToUInt16(sysTime.wMonth-1);
                              sysTime.wDay
      =Convert.ToUInt16(30);
                          }

                          
      else if(sysTime.wMonth==1)
                          
      {
                              sysTime.wMonth
      =Convert.ToUInt16(12);
                              sysTime.wDay
      =Convert.ToUInt16(31);
                              sysTime.wYear
      =Convert.ToUInt16(sysTime.wYear-1);
                          }

                          
      else if(sysTime.wMonth==3)
                          
      {
                              sysTime.wMonth
      =Convert.ToUInt16(2);
                              
      if(sysTime.wYear%4==0&&sysTime.wYear%100!=0)
                                  sysTime.wDay
      =Convert.ToUInt16(29);
                              
      else
                                  sysTime.wDay
      =Convert.ToUInt16(28);
                          }

                          
      else
                          
      {
                              sysTime.wMonth
      =Convert.ToUInt16(sysTime.wMonth-1);
                              sysTime.wDay
      =Convert.ToUInt16(31);
                          }


                      }

                  }

                  
      else
                  
      {
                      sysTime.wHour
      =Convert.ToUInt16(temp);
                  }


                  sysTime.wMinute 
      = Convert.ToUInt16(SysTime.Substring(10,2));
                  sysTime.wSecond 
      = Convert.ToUInt16(SysTime.Substring(12,2));
                      bool flag=Win32.SetSystemTime(ref sysTime);

                      
      return flag;
              }

       

      而对于那两个Get的方法GetSystemTimer(),和GetLocalTime()的使用,相信不成什么问题,就不多说了。

      另外,在此过程中发现一个问题,就是Visual Studio.net 2003在调式这个程序的时候经常会遇到程序不执行的情况,也不报错误,我用单步调试也是毫无反应,而关掉重新开就一点毛病都没有了,在多台电脑上都出现过。可能是Visual Studio的一个bug吧。

      发表于 @ 2006年10月01日 14:38:00|评论(loading...)|编辑

      新一篇: C#关闭应用程序时如何关闭子线程 | 旧一篇: .net中用代码生成界面控件

      评论

      #BoBo_32 发表于2008-04-17 13:51:34  IP: 61.144.195.*
      在系统中正好此文章将的内容.

      在本地使用"控制台程序"可是实现.

      但是将此代码拷贝到winform应用程序,编译可以通过,但是在运行时提示:MissingManifestResourceException异常,请问如何处理呢???

      请大虾指点一下啊:)
      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © iorikyo