Case by Case..

Wang Ting's Tech Blog
随笔 - 40, 评论 - 249, 引用 - 12

导航

工具

关于

勿发广告,谢谢配合

标签

每月存档

广告



访客

转到页面(1/3):
后页末页
2008年02月22日

偶尔在论坛里看到了这么个问题:

http://forums.microsoft.com/china/ShowPost.aspx?PostID=2651830&SiteID=15

EventLog组件没有提供验证的接口,在非域环境不方便通过远程计算机的验证。在网上搜了,这么一个常见的问题居然没有现成答案,OpenEventLog等API也没有验证参数……于是研究了一下Windows自带的EventCreate.exe的实现,原来是调用了WNetAddConnection2,依样画葫芦:

        [StructLayout(LayoutKind.Sequential)]
        private class NETRESOURCE
        {
            public int dwScope = 0;
            public int dwType = 0;
            public int dwDisplayType = 0;
            public int dwUsage = 0;
            public string lpLocalName = null;
            public string lpRemoteName = null;
            public string lpComment = null;
            public string lpProvider = null;
        };

        [DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2", CallingConvention = CallingConvention.Winapi)]
        private static extern int WNetAddConnection2(NETRESOURCE lpNetResource, string lpPassword, string lpUsername, uint dwFlags);

        private void button1_Click(object sender, EventArgs e)
        {
            NETRESOURCE myNetResource = new NETRESOURCE();
            myNetResource.lpRemoteName = @"
\\server\IPC$";

            int ret = WNetAddConnection2(myNetResource, "password", @"server\Administrator", 0);

            eventLog1.Source = "EventCreate";
            eventLog1.Log = "Application";
            eventLog1.MachineName = "server";
            eventLog1.WriteEntry("Test");
        }

走的RPC。Event Source需要事先创建好,目标机器的Remote Registry服务需要开启。

此外也可以考虑走WMI路线,具体没有详细研究……

posted on 2008-02-22 15:20:00 by TingWang  评论(2) 阅读(2954)

 
2007年12月11日


Visual Studio 2008 Setup Troubleshooting Guide
http://blogs.msdn.com/varungupta/archive/2007/12/04/visual-studio-2008-setup-troubleshooting-guide.aspx

Visual Studio 2008 and .NET Framework 3.5 setup log files
http://blogs.msdn.com/astebner/archive/2007/07/31/4156781.aspx

关于Web Authoring Component的安装:

Setup program crashes when you try to install a 2007 Office suite on a 64-bit version of Windows Server 2003
http://support.microsoft.com/?id=927476

Common problems installing Microsoft Web Authoring Component
http://blogs.msdn.com/mikhailarkhipov/archive/2007/11/20/common-problems-installing-microsoft-web-authoring-component.aspx

12/24补充:

Updated version of the .NET Framework cleanup tool that can remove the .NET Framework 3.5 RTM
http://blogs.msdn.com/astebner/archive/2007/12/04/6659905.aspx

Uninstalling Visual Studio 2008 带有VS 2008的自动卸载工具
http://msdn2.microsoft.com/en-us/vs2008/bb968856.aspx

Vista上安装的时候要小心,不可随意重启:

How to avoid OS reboot prompt when installing the .NET Framework 3.5 on Windows Vista
http://blogs.msdn.com/astebner/archive/2007/11/13/6190778.aspx

还有著名的WPF Designer Crash问题,貌似至今还没有出官方说法,持续期待中……

Visual Studio 2008 May Experience Crashing Behavior When Run on Windows Vista version 6.0.6000 (RTM) PCs
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2567335&SiteID=1

posted on 2007-12-11 14:48:00 by TingWang  评论(3) 阅读(4786)

 
2007年12月03日

这件事,这些年来已经和客户说了无数遍:这是客户端浏览器的行为,我们在服务器端的代码|程序中没有控制,所以是做不到的……

今天一个偶然的机会发现原来我竟然错了,Windows XP SP2带的IE 6早已经实现了这个功能了……

CONTENT Attribute | content Property
http://msdn2.microsoft.com/en-us/library/ms533689.aspx

技术的车轮原来就这么不停的在向前滚动着……

 

posted on 2007-12-03 11:38:00 by TingWang  评论(6) 阅读(3871)

 
2007年02月15日

 

1.    Make a Win32 or MFC DLL with Visual C++. Assume it is named “myfile.dll”.

 

2.    Get a pair of certificate and private key (e.g. “testcert.cer” and “testcert.pvk”). As a requirement for WinSxS, the certificate key must be at least 2048 bits. As a result, we cannot use “makecert” to make it. We can request one from our Certificate Authority. Please choose the proper provider, so that we can specify 2048 bits as the “Key Size”.

 

Store the .cer, .pvk and the .dll file in the same folder.

 

3.    Open a Visual Studio 2005 Command Prompt, so that we can use the SDK utilities directly. Issue the following command to get the publicKeyToken from the .cer certificate:

 

pktextract testCert.cer

 

We will get the publicKeyToken in the output (“bb28decf5785d648”):

 

Microsoft (R) Side-By-Side Public Key Token Extractor 1.1.3.0

Copyright (C) Microsoft Corporation 2000-2002. All Rights Reserved

 

 

Certificate: "CATry-Catch" - 2048 bits long

        publicKeyToken="bb28decf5785d648"

 

Pktextract.exe

http://msdn2.microsoft.com/en-us/library/aa375670.aspx

 

4.    Use Notepad to create a manifest file (e.g. “myfile.manifest”), with the following content:

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity

        type="win32"

        name="Microsoft.Windows.MySampleAssembly"

        version="1.0.0.0"

        processorArchitecture="x86"        

        publicKeyToken="bb28decf5785d648"/>

    <file name="myfile.dll" hashalg="SHA1/>

</assembly>

 

Note that we need to put the public key token extracted from the previous step into the manifest. The following is the reference to assembly manifest files:

 

Assembly Manifests

http://msdn2.microsoft.com/en-us/library/aa374219.aspx

 

5.    Issue the following command:

 

mt.exe -manifest myfile.manifest -hashupdate -makecdfs

 

After this, the content of the manifest file (“myfile.manifest”) will contain the hash for the DLL (“myfile.dll”). The -makecdfs option generates a file named “myfile.manifest.cdf” that describes the contents of the security catalog that will be used to validate the manifest.

 

Mt.exe

http://msdn2.microsoft.com/en-us/library/aa375649.aspx

 

6.    Issue the following command further to build a verification catalog:

 

makecat myfile.manifest.cdf

 

MakeCat

http://msdn2.microsoft.com/en-us/library/aa386967.aspx

 

7.    Use the “pvkimprt” utility to generate a “.pfx” file with the “.pvk” and “.cer” file:

 

pvkimprt -pfx testcert.cer testCert.pvk

 

The utility can be downloaded from the following site:

 

http://office.microsoft.com/downloads/2000/pvkimprt.aspx

 

Assume we named the PFX format file as “testcert.pfx”.

 

8.    Use the SignTool to sign the catalog with the certificate:

 

signtool sign /f testcert.pfx /p PasswordForPrivateKey /du http://www.mycompany.com/MySampleAssembly /t http://timestamp.verisign.com/scripts/timstamp.dll myfile.cat

 

Please replace “PasswordForPrivateKey” with the actual password.

 

SignTool

http://msdn2.microsoft.com/en-us/library/aa387764.aspx

 

At this stage we have the 3 files required for deploying the shared Side-by-Side assembly:

 

myfile.dll

myfile.cat

myfile.manifest

 

Then we can go to the Windows Installer part.

 

1.    Use Visual Studio .Net to create a Setup project. Add the 3 files above into the project and build the project.

 

2.    Use Orca to open the built MSI file for further editing.

 

How to use the Orca database editor to edit Windows Installer files

http://support.microsoft.com/?id=255905

 

3.    In the “File” table, we should see 3 rows, each’s “FileName” column points to one of the 3 files (e.g. “myfile.dll”, “myfile.cat” and “myfile.manifest”). We edit the rows for “myfile.cat” and “myfile.manifest”, by replacing their “Component_” column with the value from the “Component_” column of the “myfile.dll” row. This effectively assign the 3 files into the same component originally used by “myfile.dll”. Please take a note of the 2 component names (e.g. the original values from the “Component_” column of “myfile.manifest” and “myfile.cat” rows) being replaced.

 

4.    Go to the “Component” table. We should see 3 rows here. Let’s delete the 2 rows whose “Component” columns have the same values we replaced in step 3 (e.g. the original component names for “myfile.manifest” and “myfile.cat”).

 

5.    Go to the “FeatureComponent” table, repeat step 4 and delete the unnecessary component rows for “myfile.manifest” and “myfile.cat” also.

 

6.    Go to the “MsiAssembly” table, add a new row:

 

Component_: <the value taken from the “File” table, “Component” column for “myfile.dll”, “myfile.manifest” or “myfile.cat” (these 3 “Component” columns should contain the same value after step 3)>

Feature_: DefaultFeature (This is the only feature name in Visual Studio 2005/2003 Setup Project. It can also be found from the “Feature” table or “FeatureComponent” table.)

File_Manifest: <the value taken from the “File” table, “File” column for the file “myfile.manifest>

File_Application: <Leave this empty>

Attribute: 1

 

7.    Go to the “MsiAssemblyName” table, add 5 rows, whose “Component_” columns are all the value taken from the “File” table, “Component” column for “myfile.dll”.

 

The “Name” columns and “Value” columns of the 5 rows are taken from the content of the manifest file:

 

Name                                      Value

type                                win32

name                               Microsoft.Windows.MySampleAssembly

version                             1.0.0.0

processorArchitecture         x86

publicKeyToken                  bb28decf5785d648

 

8.    Save the MSI file and exit Orca. (Do not use “Save As” command.

 

The resultant MSI file should be able to install our “myfile.dll” as Side-by-Side shared assembly into the WinSxS folder.

 

Here are some addition references related to the subject:

 

Assembly Signing Example

http://msdn2.microsoft.com/en-us/library/aa374228.aspx

 

Installing Win32 Assemblies for Side-by-Side Sharing on Windows XP

http://msdn2.microsoft.com/en-us/library/aa369532.aspx

 

posted on 2007-02-15 17:30:00 by TingWang  评论(0) 阅读(715)

 
2006年12月01日

Useful Logging Options in .Net:

http://blog.joycode.com/tingwang/articles/80349.aspx

持续更新中……这可能是我写过的所有东西中最有用的一样,就看识不识货了……如果有补充,请留言,谢谢……

posted on 2006-12-01 13:27:00 by TingWang  评论(4) 阅读(6847)

 

I am posting this as a small sample I worked for MCS. It demonstrate some bacic usages of .Net 2.0 WinForm WebBrowser control:

 

1. How we can hook up the HTML events with managed code.

2. How to get the current element being edited in the WebBrowser, either by mouse or by keyborad typing.

3. How we can identify the tags in the DOM document.

 

===========================Form1.cs===========================

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Xml;

using System.Xml.Xsl;

using System.Runtime.InteropServices;

 

namespace WebBrowserSample

{

            public partial class Form1 : Form

            {

                        public Form1()

                        {

                                    InitializeComponent();

                        }

 

                        // Holding the XML document.

                        private XmlDocument xdoc = new XmlDocument();

                        // Holding the XmlElement (e.g. <food>) from the XmlDocument being edited.

                        private XmlElement currentEditingXMLElement;

                        // Holding the HtmlElement (e.g. <div> with foodid attribute) from the HtmlDocument in the WebBrowser control.

                        private HtmlElement currentEditingHTMLElement;

 

                        [DllImport("user32.dll")]

                        public static extern bool GetCaretPos(ref Point pt);

 

                        private void button1_Click(object sender, EventArgs e)

                        {

                                    // Routine work. Load the XML into the control as well as the XmlDocument.

                                    // No need to apply XSLT further as the XML already specifies so with "xml-stylesheet".

                                    webBrowser1.Navigate(Application.StartupPath + "\\data.xml");

                                    xdoc.Load(Application.StartupPath + "\\data.xml");

                                    webBrowser1.Document.Click += new HtmlElementEventHandler(Document_Click);

                                    mshtml.IHTMLDocument2 hdoc = (mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;

                                    hdoc.designMode = "On";

                                    button1.Enabled = false;

                                    webBrowser1.Document.MouseMove += new HtmlElementEventHandler(Document_MouseMove);

 

                                    while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)

                                    {

                                                Application.DoEvents();

                                    }

 

                                   webBrowser1.Document.AttachEventHandler("onkeydown", new EventHandler(this.Document_KeyDown));

                        }

 

                        void Document_KeyDown(object sender, EventArgs e)

                        {

                                    Point p = new Point(0, 0);

                                    bool bResult = GetCaretPos(ref p);

                                    HtmlElement he = webBrowser1.Document.GetElementFromPoint(p);

                                    Console.WriteLine(he.InnerText);

                        }

 

                        // Holding the reference of the previous element that mouse moves over.

                        private HtmlElement previousMovedElement;

 

                        void Document_MouseMove(object sender, HtmlElementEventArgs e)

                        {

                                    // Get the current element under mouse cursor

                                    HtmlElement movingElement = webBrowser1.Document.GetElementFromPoint(e.MousePosition);

                                    // Is the element the same one as we recorded previously? If yes, we just ignore it.

                                    if (movingElement != previousMovedElement)

                                    {

                                                // The previous element we move over is a HTML span and now we are moving out of it.

                                                if ((previousMovedElement != null) && (previousMovedElement.TagName.ToLower() == "span"))

                                                {

                                                            // Restore the color for the previous span element.

                                                            mshtml.HTMLSpanElement previousSpan = (mshtml.HTMLSpanElement)previousMovedElement.DomElement;

                                                            object objColor = previousSpan.getAttribute("oldColor", 0);

                                                            string strColor = (objColor != null) ? objColor.ToString() : "";

                                                            if (!string.IsNullOrEmpty(strColor))

                                                                        previousSpan.style.color = strColor;

                                                            else

                                                                        previousSpan.style.removeAttribute("color", 0);

                                                }

                                                // We are moving to a span element.

                                                if (movingElement.TagName.ToLower() == "span")

                                                {

                                                            // Let's remember its current color, using an additiona attribute "oldColor":

                                                            mshtml.HTMLSpanElement span = (mshtml.HTMLSpanElement)movingElement.DomElement;

                                                            if (span.style.color != null)

                                                                        span.setAttribute("oldColor", span.style.color.ToString(), 0);

                                                            else

                                                                        span.setAttribute("oldColor", "",0);

                                                            span.style.color = "blue";

                                                }

                                                // Remember the last element we move over, no matter it is a span or not.

                                                previousMovedElement = movingElement;

                                    }

                        }

 

                        void Document_Click(object sender, HtmlElementEventArgs e)

                        {

                                    // Get the element being clicked.

                                    HtmlElement clickedElement = webBrowser1.Document.GetElementFromPoint(e.MousePosition);

                                    string id = null;

 

                                    // Go up in the hierarchy until we locate the "div" with "foodid" attribute.

                                    // Then we can find out the details from the XML with the same ID.

                                    while (clickedElement.Parent != null)

                                    {

                                                id = clickedElement.GetAttribute("foodid");

                                                if (!string.IsNullOrEmpty(id))

                                                {

                                                            currentEditingHTMLElement = clickedElement;

                                                            break;

                                                }

                                                else

                                                            clickedElement = clickedElement.Parent;

                                    }

 

                                    // Make sure that we find the id.

                                    if (!string.IsNullOrEmpty(id))

                                    {

                                                // XPath query for locating the food element with same id from the XmlDocument.

                                                currentEditingXMLElement = (XmlElement)(xdoc.SelectSingleNode("//food[@id=" + id + "]"));

                                                // Create the wrapper class, so that we can associate it with the PropertyGrid.

                                                FoodClass currentEditingFoodClass = new FoodClass();

                                                currentEditingFoodClass.Description = currentEditingXMLElement.SelectSingleNode("description").InnerText;

                                               currentEditingFoodClass.Name = currentEditingXMLElement.SelectSingleNode("name").InnerText;

                                                currentEditingFoodClass.Price = currentEditingXMLElement.SelectSingleNode("price").InnerText;

                                                currentEditingFoodClass.Calories = int.Parse(currentEditingXMLElement.SelectSingleNode("calories").InnerText);

                                                currentEditingFoodClass.Id = id; //This property is unused actually.

                                                // Associate the callback routine, so that we can update the HTML view.

                                                currentEditingFoodClass.ContentChanged += new EventHandler(currentEditingFoodClass_ContentChanged);

                                                propertyGrid1.SelectedObject = currentEditingFoodClass;

                                    }

                                    richTextBox1.Text = clickedElement.OuterHtml;

                        }

 

                        void currentEditingFoodClass_ContentChanged(object sender, EventArgs e)

                        {

                                    ConentChangedEventArgs ce = (ConentChangedEventArgs)e;

                                    string field = ce.Field.ToLower();

                                   

                                    // Update the content in the XmlDocument