开发截屏软件的收获

开发截屏软件的收获:
1、可以使用System.Windows.Deployment.Current.Dispatcher.BeginInvoke(...)来在UI的Dispatcher上执行任务,而且避免引用Application,可以在类库中使用。
2、在普通.net中可以使用自定义SynchronizationContext子类进行任务调度,然后SynchronizationContext.SetSynchronizationContext设置当前的任务调度器、消息泵,但是在Silverlight中是不能调用SynchronizationContext.SetSynchronizationContext,因为SynchronizationContext.SetSynchronizationContext标记为 [SecurityCritical],标记为 [SecurityCritical]的都不能被UserCode调用。
为SynchronizationContext.Current.Post((obj) => { Capture(); }, null)来进行任务调用。

3、DllImport工具包:调用 Dehydrator.AllowMultitasking = true;启用多任务,启用以后DispatcherTimer停止了,但是可以在页面中通过BackgroundWorkder或者Thread启动后台线程,在后台线程中不断循环,这样退出后仍然可以继续运行。
4、DllImport工具包: Dispatcher.BeginInvoke是靠DispatcherTimer进行任务调度的。DispatcherTimer在应用到后台的时候是不触发Tick事件的、Webclient在应用到后台的时候是不启动异步请求的,虽然调用OpenWriteAsync不报错、Phone.KeyboardHook.StartHook音量键、拍照键都可以。
5、在非UI线程中不能new WritableBitmap,但是可以先在UI线程中new WritableBitmap,然后在线程中还可以操作它。
6、PC中调用Connectivity来操作设备、模拟器、部署应用等:
添加对C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.SmartDevice.Connectivity\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.SmartDevice.Connectivity.dll、C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualStudio.DeviceConnectivity.Interop.10.0\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.DeviceConnectivity.Interop.10.0.dll的引用。代码
        internal static DeviceInfo[] GetDevices()
        {
            List<DeviceInfo> list = new List<DeviceInfo>();
            DatastoreManager manager = new DatastoreManager(0x409);
            foreach (Platform platform in manager.GetPlatforms())
            {
                foreach (Device device in platform.GetDevices())
                {
                    list.Add(new DeviceInfo(platform.Id.ToString(), device.Id.ToString(), device.Name));
                }
            }
            return list.ToArray();
        }
       
           var deviceInfo = GetDevices()[0];
            DatastoreManager manager = new DatastoreManager(0x409);
            Device device = manager.GetPlatform(new ObjectId(deviceInfo.PlatformId)).GetDevice(new ObjectId(deviceInfo.DeviceId));
            device.Connect();
 可以调用device的InstallAppllication等方法对手机进行操作。 
尝试调用FileDeployer的方法在PC和手机之间进行文件传输:
            var fieldmConmanServer= device.GetType().GetField("mConmanServer", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            var mConmanServer =  fieldmConmanServer.GetValue(device);
            Type typeFileDeployer = typeof(FileDeployer);
            var constr = typeFileDeployer.GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0];
            FileDeployer dep = (FileDeployer)constr.Invoke(new object[] { mConmanServer });
            Guid appID = new Guid("{730189d4-189f-4238-a6d7-3d78a8680d1b}");
if (device.IsApplicationInstalled(appID))
{
    string filename = @"\Applications\Data\" + appID + @"\Data\IsolatedStore\screen.jpg";
    dep.SendFile("c:/boot.ini", @"\DOCFILE\a.txt");
    dep.ReceiveFile(filename, @"screen.jpg");
    //dynamic fileDep = new FileDeployer(mConmanServer);
    MessageBox.Show("ok");
}
else
{
    MessageBox.Show("notinstall");
}
但是调用失败,ReceiveFile、SendFile报错没有权限。

7、尝试调用Dispatcher的Dispatch干扰消息泵
//var d = Dispatcher;
            ////wp7中只能反射调用public成员
            //var methodTimerTick = d.GetType().GetMethod("Dispatch", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            //methodTimerTick.Invoke(d, new object[] {8});
            ////d.TimerTick(null, null);
但是失败,因为WindowsPhone中的反射不能调用private成员。

8、Socket发送的时候不是Send(buffer,...)就都传出去了,因为并不是都会发出去,需要自己进行控制,Send的返回值是本次发送的数据量
void sendpost()

 sockaddr_in serverAddr;
 SOCKET sock;
 hostent * host;
 host = gethostbyname("192.168.1.100");
 if(host==NULL)
 {
  return;
 }

 sock = socket(AF_INET, SOCK_STREAM,0);
 serverAddr.sin_addr = *(struct in_addr*)host->h_addr;
 serverAddr.sin_family = AF_INET;
 serverAddr.sin_port = htons(9999);//25

 if(connect(sock,(const sockaddr*)&serverAddr,sizeof(sockaddr))==SOCKET_ERROR)
 {
  int i = WSAGetLastError();
  closesocket(sock);
  return;
 }

 char buffer[1024]; 

 sprintf(buffer,"POST /UploadScreenCapture.ashx HTTP/1.1\r\n");//from为char数据。存储发送地址
 send(sock,buffer,strlen(buffer),0); 

 char *data = (char*)malloc(1024*1000*sizeof(char));//要发送的数据。
 for(int i=0;i<sizeof(data)/sizeof(char);i++)
 {
  data[i] = 5;
 }
 sprintf(buffer,"Content-Length: %d\r\n\r\n",sizeof(data));//from为char数据。存储发送地址
 send(sock,buffer,strlen(buffer),0);

 int len = sizeof(data)/sizeof(char);
 int res;
 int pos = 0; //下一次发送需要开始的位置:
 while(pos < len)
 {
  res = send(sock, data + pos , len - pos, 0);
  if(res <=0)
   break;
  pos += res;
 }


 send(sock,data,sizeof(data),0);
 //free(data);

 closesocket(sock);
 
 return;
}
9、WP7Network、DllImport等生成的dll一般都是为ARM真机编译的,如果要在模拟器上运行,需要用WinCE编译器编译成X86的dll因为模拟器是X86架构的。

posted @ 2011-06-16 00:14  杨中科  阅读(1302)  评论(1编辑  收藏  举报