『取巧』VS2015试用期过后 继续试用

背景:

个人电脑 安装的 VS2015 Community 社区版。

一直用得挺好,都忘了要登录。

 

直到近来,30天试用期过 —— VS弹窗:要登录用户名、密码 才能继续使用。

但是,输入了无数次 邮箱,到下一步时,都弹出一个 白屏窗口 —— 死活没法登录成功。

 

登录不成功,日子还得过。

尊重著作权、版权 —— 破解VS这种事,还是不做的好(虽然能力可及)。

 

另辟蹊径:

试着通过 Win32 发送消息:关闭 弹出窗体。

但是 弹出窗体接收到 关闭消息后,整个VS 依然全部关掉了。

再尝试了一下:

如果先 修改系统时间,让修改后的系统时间 就是 试用期范围 —— 再关闭弹窗,VS 主窗体 没关闭。

 

思路明确:

> 监控系统所有窗体。

> 如果有窗体标题是 “Microsoft Visual Studio 帐户设置” 则开始 如下操作

> 修改系统时间 到 试用期范围。

> 发送 WM_CLOSE 消息,关闭 弹出窗体。

> 将系统时间 修改回来。

 

相关源码 150行:

  1     class Program
  2     {
  3         /// <summary>
  4         /// Visual Studio 2015 可以正常启用的 试用期 时间
  5         /// </summary>
  6         public static DateTime VisualStudioDate
  7         {
  8             get { return Convert.ToDateTime(ConfigurationManager.AppSettings["VisualStudioDate"] ?? "2018-05-01"); }
  9         }
 10 
 11 
 12 
 13         static void Main(string[] args)
 14         {
 15             while(true)
 16             {
 17                 List<Win32API.WindowInfo> list = Win32API.EnumWindows();
 18                 List<Win32API.WindowInfo> list2 = list.FindAll(x => x.szWindowName == "Microsoft Visual Studio 帐户设置");
 19 
 20                 if (list2.Count >= 1)
 21                 {
 22                     //将系统时间设置为 可试用期
 23                     DateTime nowTime = DateTime.Now;
 24                     DateTime vsTime = VisualStudioDate;
 25                     double timeSpanMS = (nowTime - vsTime).TotalMilliseconds;
 26                     Win32API.SetSystemTime(vsTime);
 27 
 28                     foreach (Win32API.WindowInfo item in list2)
 29                     {
 30                         try
 31                         {
 32                             Console.WriteLine(string.Format("即将关闭 \"{0}\" 0x{1}", item.szWindowName, item.hWnd.ToString("X8")));
 33                             Win32API.SendMessage(item.hWnd, Win32API.WM_CLOSE, 0, 0);
 34                         }
 35                         catch { }
 36                     }
 37 
 38                     Thread.Sleep(2000);
 39 
 40                     //将系统时间还原为 实际日期
 41                     DateTime nowTime2 = DateTime.Now;
 42                     double timeSpanMS2 = (nowTime2 - vsTime).TotalMilliseconds;
 43                     DateTime realTime = vsTime.AddMilliseconds(timeSpanMS + timeSpanMS2);
 44                     Win32API.SetSystemTime(realTime);
 45                 }
 46 
 47                 //死循环, 休眠5秒
 48                 Thread.Sleep(5000);
 49             }
 50         }
 51 
 52 
 53 
 54 
 55     }
 56 
 57     public class Win32API
 58     {
 59         public const int WM_CLOSE = 0x0010;
 60         private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
 61 
 62         [DllImport("User32.dll", EntryPoint = "SendMessage")]
 63         public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
 64 
 65 
 66         #region  获取所有窗体句柄
 67 
 68         //Copyright © http://www.cnblogs.com/oraclejava/articles/1549025.html
 69 
 70         [DllImport("user32.dll")]
 71         private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
 72         [DllImport("user32.dll")]
 73         private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
 74         [DllImport("user32.dll")]
 75         private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
 76         public struct WindowInfo
 77         {
 78             public IntPtr hWnd;
 79             public string szWindowName;
 80             public string szClassName;
 81 
 82             public override string ToString()
 83             {
 84                 return "0x" + hWnd.ToString("X8") + " '" + szWindowName + "' '" + szClassName + "'";
 85             }
 86         }
 87 
 88         public static List<WindowInfo> EnumWindows()
 89         {
 90             List<WindowInfo> wndList = new List<WindowInfo>();
 91 
 92             EnumWindows(delegate(IntPtr hWnd, int lParam)
 93             {
 94                 WindowInfo wnd = new WindowInfo();
 95                 StringBuilder sb = new StringBuilder(256);
 96                 wnd.hWnd = hWnd;
 97                 GetWindowTextW(hWnd, sb, sb.Capacity);
 98                 wnd.szWindowName = sb.ToString();
 99                 GetClassNameW(hWnd, sb, sb.Capacity);
100                 wnd.szClassName = sb.ToString();
101                 wndList.Add(wnd);
102                 return true;
103             }, 0);
104 
105             return wndList;
106         }
107 
108         #endregion
109 
110 
111         #region  操作系统 时间修改
112 
113         public static bool SetSystemTime(DateTime newDateTime)
114         {
115             SystemTime sysTime = new SystemTime();
116             sysTime.wYear = Convert.ToUInt16(newDateTime.Year);
117             sysTime.wMonth = Convert.ToUInt16(newDateTime.Month);
118             sysTime.wDay = Convert.ToUInt16(newDateTime.Day);
119             sysTime.wHour = Convert.ToUInt16(newDateTime.Hour);
120             sysTime.wMinute = Convert.ToUInt16(newDateTime.Minute);
121             sysTime.wSecond = Convert.ToUInt16(newDateTime.Second);
122             sysTime.wMiliseconds = (ushort)newDateTime.Millisecond;
123             return SystemDateTime.SetLocalTime(ref sysTime);
124         }
125 
126         private class SystemDateTime
127         {
128             [DllImport("Kernel32.dll")]
129             public static extern bool SetLocalTime(ref SystemTime sysTime);
130 
131             [DllImport("Kernel32.dll")]
132             public static extern void GetLocalTime(ref SystemTime sysTime);
133         }
134 
135         [StructLayout(LayoutKind.Sequential)]
136         private struct SystemTime
137         {
138             public ushort wYear;
139             public ushort wMonth;
140             public ushort wDayOfWeek;
141             public ushort wDay;
142             public ushort wHour;
143             public ushort wMinute;
144             public ushort wSecond;
145             public ushort wMiliseconds;
146         }
147 
148         #endregion
149 
150     }

 

项目编译:

新建一个 WinForm 程序。

将上面的代码 复制替换。

编译之后,将 exe 创建一个 快捷方式,放到 “启动” 菜单中,开机就启动,让exe在后台运行即可。

 

操作争议:

作者非常尊重 软件著作权、版权 —— 无意伤害微软利益。

用这种方式 延长试用,似乎有两个争议:修改系统时间、发送 WM_CLOSE 消息。

 

> 修改系统时间 是一种 普通操作,任何人都可以进行。【不具备争议性】

> 发送 WM_CLOSE 消息,一个程序给另一个程序发送消息,改变另外的程序的行为【有点外挂的味道】。 —— 但仔细一想:电脑关机时,系统会给每一个程序 都发送 WM_CLOSE 消息。这样一想,就突然不觉得侵权了。

 

 

尊重知识产权:

作者非常尊重 软件著作权、版权 —— 如果本文的操作 损害了 微软的利益,请及时联系作者,删除、修改 此文。

 

posted on 2018-05-22 17:09  InkFx  阅读(6355)  评论(3编辑  收藏  举报