http://technet.microsoft.com/zh-CN/sysinternals

http://technet.microsoft.com/en-us/sysinternals/bb896647

我们利用debugView 命令可以自动生成log文件,而且是atomic。

cmd -h就可以看到了。

用ShellExeccute

从codeProject 搜索debugview

刚找到一些 http://www.codeproject.com/Articles/13345/DbMon-NET-A-simple-NET-OutputDebugString-capturer

http://www.codeproject.com/Articles/1053/Using-an-output-stream-for-debugging

===============================================

看到Mechanism-of-OutputDebugString,

最重要是的http://unixwiz.net/techtips/OutputDebugString.txt

/*
* pseudocode for OutputDebugString
*
* from KERNEL32.DLL ver 5.0.2195.6794
*
* Reverse engineered by Steve Friedl (steve@unixwiz.net)
*/
void OutputDebugStringA(LPTSTR *lpString)
{
DBWIN_buffer *pDBBuffer = ;
HANDLE hFileMap = ;
HANDLE hBufferEvent = ;
HANDLE hDataEvent = ; // if we can't make or acquire the mutex, we're done if ( hDbwinMutex == )
hDbwinMutex = setup_mutex(); if ( hDbwinMutex == ) return; (void) WaitForSingleObject(hDbwinMutex, INFINITE); hFileMap = OpenFileMapping(FILE_MAP_WRITE, FALSE, "DBWIN_BUFFER"); pDBBuffer = (DBWIN_buffer *) MapViewOfFile(
hFileMap,
FILE_MAP_READ|FILE_MAP_WRITE,
, // file offset high
, // file offset low
); // # of bytes to map (entire file) hBufferEvent = OpenEvent( SYNCHRONIZE, FALSE, "DBWIN_BUFFER_READY");
hDataEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY"); const char *p = lpString;
int len = strlen(lpString); while ( len > )
{
if ( WaitForSingleObject(hBufferEvent, *) != WAIT_OBJECT_0 )
{
/* ERROR: give up */
break;
} // populate the shared memory segment. The string
// is limited to 4k or so.
pBuffer->dwProcessId = GetCurrentProcessId(); int n = min(len, sizeof(pBuffer->data)-); memcpy(pBuffer->data, p, n);
pBuffer->data[n] = '\0'; len -= n;
p += n; SetEvent(hDataEvent);
} // cleanup after ourselves
CloseHandle(hBufferEvent);
CloseHandle(hDataEvent);
UnmapViewOfFile(pDBBuffer);
CloseHandle(hFileMap);
} HANDLE setup_mutex(void)
{
SID_IDENTIFIER_AUTHORITY SIAWindowsNT = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIAWorld = SECURITY_WORLD_SID_AUTHORITY; SID *pSidSYSTEM = , //
*pSidAdmins = ,
*pSidEveryone = ; AllocateAndInitializeSid(&SIAWindowsNT,
, SECURITY_LOCAL_SYSTEM_RID,
, , , , , , ,
&pSidSYSTEM); AllocateAndInitializeSid(&SIAWindowsNT,
, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
, , , , , ,
&pSidAdmins); AllocateAndInitializeSid(&SIAWorld,
, SECURITY_WORLD_RID,
, , , , , , ,
&pSidEveryone); const DWORD dwACLSize = GetLengthSid(pSidSYSTEM)
+ GetLengthSig(pSidAdmins)
+ GetLengthSig(pSidEveryone)
+ ; ACL *pACL = GlobalAlloc( , dwACLSize ); InitializeAcl(pACL, dwACLsize, ACL_REVISION ); AddAccessAllowedAce(pACL,
ACL_REVISION,
SYNCHRONIZE | READ_CONTROL | MUTEX_QUERY_STATE,
pSidEveryone); AddAccessAllowedAce(pACL,
ACL_REVISION,
MUTEX_ALL_ACCESS,
pSidSYSTEM); AddAccessAllowedAce(pACL,
ACL_REVISION,
MUTEX_ALL_ACCESS,
pSidAdmins); SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE); SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof sa); sa.bInheritHandle = FALSE;
sa.nLength = sizeof sa;
sa.lpSecurityDescriptor = &sd; HANDLE hMutex = CreateMutex(&sa, FALSE, "DBWinMutex"); FreeSid(pSidAdmins);
FreeSid(pSidSYSTEM);
FreeSid(pSidEveryone);
GlobalFree(pACL); return hMutex;
}

http://www.codeproject.com/Articles/23776/Mechanism-of-OutputDebugString

没想到看到了干货。   在这  ===》》》http://unixwiz.net/techtips/outputdebugstring.html

Steve Friedl's Unixwiz.net Tech Tips

Understanding Win32 "OutputDebugString"

Hardcore Win32 developers are probably familiar with the OutputDebugString() API function that lets your program talk with a debugger. It's handier than having to create a logfile, and all the "real" debuggers can use it. The mechanism by which an application talks to the debugger is straightforward, and this Tech Tip documents how the whole thing works.

This Tech Tip was prompted first by our observation that OutputDebugString() didn't always work reliably when Admin and non-Admin users tried to work and play together (on Win2000, at least). We suspected permissions issues on some of the kernel objects involved, and in the process ran across enough information that we had to write it up.

We'll note that though we're using the term "debugger", it's not used in the Debugging API sense: there is no "single stepping" or "breakpoints" or "attach to process" going on like one might find in MS Visual C or some real interactive development environment. Any program that implements the protocol is a "debugger" in this sense. This could be a very simple command-line tool, or one more advanced such as DebugView from the very smart guys at SysInternals.

Application program usage

The <windows.h> file declares two version of the
OutputDebugString() function - one for ASCII, one for Unicode -
and unlike most of the Win32 API, the native version is ASCII. Most of
the Win32 API is Unicode native.

Simply calling OutputDebugString() with a NUL-terminated string buffer
causes the message to appear on the debugger, if there is one. Common
usage builds a message and sends it

sprintf(msgbuf, "Cannot open file %s [err=%ld]\n", fname, GetLastError());

OutputDebugString(msgbuf);

but in practice many of us create a front-end function that allows us to use printf-style formatting. The odprintf() function formats the string, insures that there is a proper CR/LF at the end (removing any previous line terminations), and sends the message to the debugger.

#include <stdio.h>
#include <stdarg.h>
#include <ctype.h> void __cdecl odprintf(const char *format, ...)
{
char buf[4096], *p = buf;
va_list args;
int n; va_start(args, format);
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
va_end(args); p += (n < 0) ? sizeof buf - 3 : n; while ( p > buf && isspace(p[-1]) )
*--p = '\0'; *p++ = '\r';
*p++ = '\n';
*p = '\0'; OutputDebugString(buf);
}

Then using it in code is easy:

        ...
odprintf("Cannot open file %s [err=%ld]", fname, GetLastError());
...

We've been using this for years.

The protocol

Passing of data between the application and the debugger is done via a 4kbyte chunk of shared memory, with a Mutex and two Event objects protecting access to it. These are the four kernel objects involved:

object name object type
DBWinMutex Mutex
DBWIN_BUFFER Section (shared memory)
DBWIN_BUFFER_READY Event
DBWIN_DATA_READY Event

The mutex generally remains on the system all the time, but the other three are only present if a debugger is around to accept the messages. Indeed - if a debugger finds the last three objects already exist, it will refuse to run.

The DBWIN_BUFFER, when present, is organized like this structure. The process ID shows where the message came from, and string data fills out the remainder of the 4k. By convention, a NUL byte is always included at the end of the message.

struct dbwin_buffer {
DWORD dwProcessId;
char data[4096-sizeof(DWORD)];
};

When OutputDebugString() is called by an application, it takes these steps. Note that a failure at any point abandons the whole thing and treats the debugging request as a no-op (the string isn't sent anywhere).

  1. Open DBWinMutex and wait until we have exclusive access to it.
  2. Map the DBWIN_BUFFER segment into memory: if it's not found, there is no debugger running so the entire request is ignored.
  3. Open the DBWIN_BUFFER_READY and DBWIN_DATA_READY events. As with the shared memory segment, missing objects mean that no debugger is available.
  4. Wait for the DBWIN_BUFFER_READY event to be signaled: this says that the memory buffer is no longer in use. Most of the time, this event will be signaled immediately when it's examined, but it won't wait longer than 10 seconds for the buffer to become ready (a timeout abandons the request).
  5. Copy up to about 4kbytes of data to the memory buffer, and store the current process ID there as well. Always put a NUL byte at the end of the string.
  6. Tell the debugger that the buffer is ready by setting the DBWIN_DATA_READY event. The debugger takes it from there.
  7. Release the mutex
  8. Close the Event and Section objects, though we keep the handle to the mutex around for later.

On the debugger front, it's a bit simpler. The mutex is not used at all, and if the events and/or shared memory objects already exist, we presume that some other debugger is already running. Only one debugger can be in the system at a time.

  1. Create the shared memory segment and the two events. If we can't, exit.
  2. Set the DBWIN_BUFFER_READY event so the applications know that the buffer is available.
  3. Wait for the DBWIN_DATA_READY event to be signaled.
  4. Extract the process ID NUL-terminated string from the memory buffer.
  5. Go to step #2

This doesn't strike us as being a low-cost way of sending messages, and the application is at the mercy of the debugger for the speed at which it runs.

The Permissions Problem

We have seen problems for years with OutputDebugString() being unreliable at times, and we're not quite sure why Microsoft has such a hard time getting this right. Curiously, the problem has always revolved around the DBWinMutex object, and it requires that we visit the permissions system to find out why this is so troublesome.

The mutex object is alive and allocated until the last program using it closes its handle, so it can remain long after the original application which created it has exited. Since this object is so widely shared, it must be given explicit permissions that allow anybody to use it. Indeed, the "default" permissions are almost never suitable, and this mistake accounted for the first bug we observed in NT 3.51 and NT 4.0.

The fix - at the time - was to create this mutex with a wide-open DACL that allowed anybody to access it, but it seems that in Win2000 these permissions have been tightened up. Superficially they look correct, as we see in this table:

SYSTEM MUTEX_ALL_ACCESS
Administrators MUTEX_ALL_ACCESS
Everybody SYNCHRONIZE | READ_CONTROL | MUTEX_QUERY_STATE

An application wishing to send debugging messages needs only the ability to wait for and acquire the mutex, and this is represented by the SYNCHRONIZE right. The permissions above are entirely correct to all all users to participate this way.

The surprise occurs when one looks at the behavior of CreateMutex() when the object already exists. In that case, Win32 behaves as if we were calling:

OpenMutex(MUTEX_ALL_ACCESS, FALSE, "DBWinMutex");

Even though we only really need SYNCHRONIZE access, it presumes the caller wishes to do everything (MUTEX_ALL_ACCESS). Because non-admins do not have these rights - only the few listed above - the mutex cannot be opened or acquired, so OutputDebugString() quietly returns without doing anything.

Even deciding to perform all software development as an administrator is not a complete fix: if there are other users (services, for instance) that run as non-admins, their debugging information will be lost if the permissions are not right.

Our feeling is that the real fix requires that Microsoft add a parameter to CreateMutex() - the access mask to use for the implied OpenMutex() if the object already exists. Perhaps someday we'll see a CreateMutexEx(), but in the medium term we have to take another approach. Instead, we'll just hard-change the permissions on the object as it lives in memory.

This revolves around the SetKernelObjectSecurity() call, and this fragment shows how a program can open the mutex and install a new DACL. This DACL remains even after this program exits, as long as any other programs maintain HANDLEs to it.

...
// open the mutex that we're going to adjust
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "DBWinMutex"); // create SECURITY_DESCRIPTOR with an explicit, empty DACL
// that allows full access to everybody SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(
&sd, // addr of SD
TRUE, // TRUE=DACL present
NULL, // ... but it's empty (wide open)
FALSE); // DACL explicitly set, not defaulted // plug in the new DACL
SetKernelObjectSecurity(hMutex, DACL_SECURITY_INFORMATION, &sd);
...

This approach is clearly going down the right road, but we still must find a place to put this logic. It would be possible to put this in a small program that could be run on demand, but this seems like it would be interruptive. Our approach has been to write a Win32 service that takes care of this.

Our dbmutex tool performs just this job: it launches at system boot time, opens or creates the mutex, and then sets the object's security to allow wide access. It then sleeps until shutdown, holding the mutex open in the process. It consumes no CPU time.

Detailed implementation

We've spent a bunch of time with IDA Pro digging into the Windows 2000 KERNEL32.DLL implementation, and we think we have a good handle on how it's working on a more precise basis. Here we present pseudocode (e.g., we've not compiled it) for the OutputDebugString() function, plus the function that creates the mutex.

We are purposely skipping most of the error checking: if things go wrong, it frees up allocated resources and exits as if no debugger were available. The goal here is to show the general behavior, not a complete reverse engineering of the code.

The "setup" function - whose name we have manufactured - creates the mutex or opens it if not already there. They go to some pains to set the security on the mutex object so that anybody can use it, though in practice we'll see that they haven't quite gotten it right.

OutputDebugString.txt

Random thoughts

It might strike some that this is a security matter, but it's really not. Non-admin users do have all the rights necessary to properly use OutputDebugString(), but due to the common mistake of "asking for more rights than required", a legitimate request is denied for a question posed in the wrong form.

But unlike most problems of this type, this is less intentional than most. Most mistakes are where the developer explicitly asks for too much (e.g., "MUTEX_ALL_ACCESS"), but this mask is implied by the behavior of CreateMutex(). This makes it harder to avoid without a change in the Win32 API.

---

While picking apart OutputDebugStringA() in KERNEL32.DLL, it became apparent how a non-admin could likely cripple a system. Once the mutex has been acquired, an application wishing to send a debug message waits up to ten seconds for the DBWIN_BUFFER_READY event to become ready, giving up if it times out. This seems like a prudent precaution to avoid starvation if the debugging system is busy.

But the earlier step, waiting for the mutex, has no such timeout. If any process on the system - including a non-privilged one - can open this mutex asking for SYNCHRONIZE rights, and just sit on it. Any other process attempting to acquire this mutex will be stopped dead in its tracks with no time limit.

Our investigation shows that all kinds of programs send random bits of debugging information (for instance, the MusicMatch Jukebox has a keyboard hook that's very chatty), and these threads are all halted by a few lines of code. It won't necessarily stop the whole program - there could be other threads - but in practice, developers don't plan on OutputDebugString() will be a denial-of-service avenue.

---

Oddly enough, we found that OutputDebugString() is not a native Unicode function. Most of the Win32 API has the "real" function to use Unicode (the "W" version), and they automatically convert from ASCII to UNICODE if the "A" version of the function is called.

But since OutputDebugString ultimately passes data to the debugger in the memory buffer strictly as ASCII, they have inverted the usual A/W pairing. This suggests that for sending a quick message to a debugger even in a Unicode program, it can be done by calling the "A" version directly:

OutputDebugStringA("Got here to place X");

Terminal Services considerations

We've discovered that in a Terminal Services environment, debug messages are generally relative to the current session and capturing global debugging messages is problematic. This appears to be because the mutex is now session relative rather than global.


Home   Stephen J. Friedl   Software Consultant   Orange County, CA USA    

======================================

嗯感觉下面的工具,做大量数据分析,性能分析,系统检测 应该很有用,留做备份吧。

http://technet.microsoft.com/zh-CN/sysinternals

Sysinternals 网站由 Mark Russinovich 和 Bryce Cogswell 于 1996 年为托管其高级系统实用工具和技术信息而创办。Microsoft 在 2006 年 7 月份收购了 Sysinternals。无论您是 IT 专业人员还是开发人员,都会发现 Sysinternals 实用工具在对 Windows 系统和应用程序进行管理、故障排除和诊断时很有帮助。如果您有关于这些实用工具或其使用方面的问题,请访问 Sysinternals 论坛,从其他用户及我们的论坛版主那里获得解答和帮助。

下载前 10 名排行榜

解决方案加速器

Microsoft 解决方案加速器是完全支持的工具、脚本、模型和最佳做法的集合,可用于对 IT 系统进行主动规划、集成和操作。

Sysinternals Live

Sysinternals Live 是一种服务,使您可以从 Web 直接执行 Sysinternals 工具,而无需查找和手动下载这些工具。只需在 Windows 资源管理器中或命令提示符处,以 http://live.sysinternals.com/<工具名称> 或 \\live.sysinternals.com\tools\<工具名称> 的形式输入工具的 Sysinternals Live 路径。

您可以使用浏览器在 http://live.sysinternals.com 上查看完整 Sysinternals Live 工具目录。

新增内容

新增内容(2010 年 1 月 19 日)

新增内容(2010 年 1 月 11 日)

  • ProcDump v1.7
    对 ProcDump(一种命令行实用工具,基于各种可选择条件生成进程的内存转储)的这一更新现在支持定期转储以及基于虚拟内存阈值的转储。
  • AccessChk v4.24
    AccessChk(一种实用工具,显示文件、注册表项、服务等的有效安全权限)现在支持进程令牌。

新增内容(2009 年 12 月 1 日)

新增内容(2009 年 11 月 3 日)

  • NewSID 的停用和计算机 SID 重复谜题
    Mark 最新的博客文章解开了重复计算机 SID 导致问题这一谜题,从而解释了 Sysinternals NewSID 工具何以退出了历史舞台。
  • Disk2vhd v1.3
    对 Disk2vhd 的这一更新通过将 Windows XP 和 Windows Server 2003 VHD 的 MBR 和引导扇区更新为与 Hyper-V 和 Virtual PC 兼容,并安装 Intelide 驱动程序(若尚未安装),从而使更多的这些 VHD 可以启动。它还通过不复制分页和休眠文件,优化了映像的创建。
  • Sigcheck v1.62
    对 Sigcheck(一种用于显示文件版本和数字签名信息的实用工具)的这一更新取消了对生成文件哈希的文件大小限制,可处理 64 位 MSI 文件,并可报告过期签名。

新增内容(2009 年 10 月 22 日)

  • Windows 7 的正式公开发布和 Mark 在第 9 频道上的访谈
    请观看 Mark 在第 9 频道上有关 Windows 7 和 Windows Server 2008 R2 内核更改的最新访谈,这些更改在今日的发布恰逢 Windows 7 的正式公开发布。他谈到内存管理、进程反射等内容,展示了有关 256 处理器系统的一些演示。

新增内容(2009 年 10 月 21 日)

  • Disk2vhd v1.1
    Disk2vhd 现在支持用于自动化的命令行选项,并修复了一个可能在转换过程中导致“无效用户缓冲区”错误的 Bug。
  • ZoomIt v4.1
    Zoomit 是一种可用于技术演示文稿的屏幕放大和批注实用工具。通过此更新,您现在可以轻松地在 LiveZoom(Vista 和 Windows 7 上支持)与绘图模式之间进行切换。
  • Coreinfo v2.0
    `Coreinfo 现在支持具有超过 64 个逻辑处理器的 IA64 和 Windows Server 2008 R2 系统。

新增内容(2009 年 10 月 7 日)

  • Disk2vhd v1.0
    我们兴奋地宣布推出一种新的 Sysinternals 工具 Disk2vhd,该工具可简化从物理系统到虚拟机 (p2v) 的迁移。只需在您要迁移的系统上运行 Disk2vhd 并指定要包含其数据的卷,Disk2vhd 便会创建一致的时间点卷快照,随后将所选卷导出到一个或多个 VHD 中,您可以将这些 VHD 添加到新的或现有的 Hyper-V 或 Virtual PC 虚拟机。

新增内容(2009 年 10 月 1 日)

  • LiveKd v3.1
    对 LiveKd(一种用于使用 Windbg 工具执行本地内核调试的工具)的这一更新添加了对具有超过 4GB RAM 的系统的支持,现在可在 x64 系统上工作(即使这些系统未以调试模式启动也无妨)。
  • Mark 的博客:突破 Windows 限制:句柄
    Mark 的“突破 Windows 限制”系列文章中的最新文章深入探讨了影响句柄使用的限制。他解释了句柄的作用,介绍系统如何管理句柄,并向您演示如何识别和调试句柄泄露。
  • Mark 在 Intel 开发人员论坛上有关 Windows 7 和 Windows Server 2008 R2 的谈话
    在旧金山举办的 Intel 开发人员论坛上,Mark 与 Shiv Kaushik(一名 Intel 同事)进行了一次联合演讲,展示了 Microsoft 和 Intel 如何在开发过程中密切合作,以确保 Windows 利用新的 Intel 处理器功能和增强功能。

windows log的更多相关文章

  1. windows log 打印语句

    1.格式化字符串(Writes formatted data to the specified string) wchar_t szMessage[260]; PWSTR pszFunction = ...

  2. windows msiexec quiet静默安装及卸载msi软件包

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoUAAAA4CAIAAAAEgBUBAAAIj0lEQVR4nO2dQXLcOAxFdbXJ0aZys6

  3. algs4 使用 DrJava 编写 Hello World on Windows

    前阶段读了 Yinwang 的博客, 对 Scheme and Lisp 产生了很大的兴趣, 用 学生模式的  DrRacket IDE一步一步开始实现 How to Design Programs. ...

  4. Windows Server 2016-配置Windows Defender防病毒排除项

    Windows Server 2016 的计算机上的 Windows Defender 防病毒自动注册你在某些排除项,由你指定的服务器角色定义. 这些排除项不会显示在Windows 安全中心应用中所示 ...

  5. 怎么打开sql server 数据库日志文件

    To Open Log File Viewer, 1. Expand Server Node > 2. Expand SQL Server Agent > 3. Expand Jobs & ...

  6. Installing a single-server IBM FileNet P8 Platform system with IBM Content Navigator

    Product documentation Abstract You can install all of the IBM FileNet P8 Platform components on a si ...

  7. Java并发学习之十九——线程同步工具之Phaser

    本文是学习网络上的文章时的总结.感谢大家无私的分享. JDK 1.7 加入了一个新的工具Phaser.Phaser的在功能上与CountDownLatch有部分重合. 以下使用Phaser类来同步3个 ...

  8. Java Concurrency - 浅析 Phaser 的用法

    One of the most complex and powerful functionalities offered by the Java concurrency API is the abil ...

  9. Java Concurrency - Fork/Join Framework

    Normally, when you implement a simple, concurrent Java application, you implement some Runnable obje ...

随机推荐

  1. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  2. CentOS下Apache+SVN+LDAP的安装与配置

    上班接近4个月了,在公司做配置管理工程师,主要是在Linux下对公司的源代码以及项目发布进行管理.4个月接触了好多新知识,也对各种工具的集成使用搞得云里来雾里去的,所以打算自己搭建一套环境,进行测试. ...

  3. cache在spring中使用

    一:参考文章 (1)http://haohaoxuexi.iteye.com/blog/2123030  Spring使用Cache,这篇文章讲的比较详细. 注:本文是对参考文章和实际使用中经验的总结 ...

  4. grunt学习

    有些时候,项目中的静态资源,比如图片占用的文件有点大,影响加载的速度,所以会选择grunt对其进行压缩打包.对于grunt其他的用法,还在继续学习中,先记录下关于grunt的一些学习. grunt是一 ...

  5. C# partial 说明

    1. 什么是局部类型? C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中. 局部类型适用于以下情况: (1) 类型特别大,不宜放在 ...

  6. 【转】MSSQL获取指定表的列名信息,描述,数据类型,长度

    /* --作用:根据特定的表名查询出字段,以及描述,数据类型,长度,精度,是否自增,是否为空等信息 --作者:wonder QQ:37036846 QQ群:.NET顶级精英群 ID:124766907 ...

  7. javascripct导图

    分别归类为: 1 .javascript变量 2. javascript运算符 3. javascript数组 4. javascript流程语句 5. javascript字符串函数 6. java ...

  8. 微信video标签全屏无法退出bug

    安卓(android)微信里面video播放视频,会被强制全屏,播放完毕后还有腾讯推荐的视频,非常讨厌..强制被全屏无法解决,但是视频播放完毕后退出播放器可以解决.方法就是视频播放完毕后,用音频aud ...

  9. 原创:Javascript Websocket客户端封装

    调试中,马马虎虎能用var LeesWebSocket = function (options) { this.defaults = { host: "127.0.0.1", po ...

  10. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...