Showing posts with label Computers. Show all posts
Showing posts with label Computers. Show all posts

Tuesday, July 08, 2008

VS 2008 - Designer error - Workflow & IIdentifierCreationService

Today I have come across this error on my Visual Studio 2008 whilst designing new Activities:

The service 'System.Workflow.ComponentModel.Design.IIdentifierCreationService' must be installed for this operation to succeed. Ensure that this service is available.

I found this entry “Making a Custom Activity Work in Your Project (even if you started with a class library) from Rob Bogue's blog.


Basically, I added a “C# class library” project to my Solution and then added classes and make them inherit from “System.Workflow.ComponentModel.Activity”.

I needed to edit the project file and add two things:

1. Some project type GUIDS

      <ProjectTypeGuids>{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

· {14822709-B5A1-4724-98CA-57A101D1B079}: This tells that it is a Workflow type project

· {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}: This tells that it is a “C# Class Library” project

2. An import statement to import .NET 3.5 Workflow code into my project

      <Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets" />


After that, I could see my activities in the Designer.

Wednesday, March 05, 2008

Visual Studio 2005 SP1 - ADS "Zone.Identifer" stroke again

Today, in order to get a new virtual machine up and running with Windows 2003 ready for .NET development I installed the free trial version of Visual Studio 2005. Usually I have got a CD with me and this time they were away (I left them back in Paris). So, I have downloaded a version from the web (Visual Studio 2005 SP1).

First issue: Error 1305 (MSI)

I tried to installed and got the 1305 error preventing the MSI to run properly ("Verify that the file exists and that you can access it").


I was again a victim of "the blocked file" (see my other blog entry IIS WEB issue ). Because, I downloaded the file from the web directly into my virtual machine (instead of using my CD/DVD) the file had an extra information "Zone.Identifier" attached top it (new use of ADS as part of the security improvement on Windows 2003 SP1). I checked the properties using Windows Explorer and I "unblocked" the file.
I shut downed the machine and rebooted it 3 times before I understood what was going on.

Before the installation kicks-off, some files need to be extracted from the MSI. When the files were extracted from the MSI into a temporary folder, they were added some extra information such as "Zone.Identifier" (I am assuming this was due to the fact that the main file setup/cab/msi files had that extra ADS information to them).
This was preventing the extraction to go further. I had to delete the temporary folder.

Second Issue: "SAFER" checks

That permitted the process to go a bit further, but it raised another issue (Error 1718):



Before the installation kicks-off, some files need to be extracted from the MSI and some "SAFER" checks are applied to them. This is documented on Heath Stewart's Blog and Microsoft web site. This was preventing the checking steps to go further. I had to install the hotfix "KB925336":


The installation was then able to finish without any further issue.

In Summary

So, here are the tips when downloading files from Internet (or other network resource) in order to install software on Windows 2003 SP1 (or above, or Windows XP SP2. I do not know about Vista, but usually Security improves and 'usability' has to give up ;)):
  • Do not forget to unblock the file (e.g. using Windows Explorer). Obviously, you have to trust the source of the file, that is your responsability.
  • If you have already run the setup file, make sure to remove all temporarily files created (they should be deleted when an installation is aborted or finished, but it is not always the case).
    • Where are the temporarily files?
      • Well look at your environment variables (using a command line window and the "set" command). Look for the variables "TEMP" and "TMP". Be careful, those settings are set at the user level, so check them for the user account you are using to do the installation.
I have installed VS 2005 SP1, so I think I will soon develop a quick tool that scan for ADS information on the files.

Thursday, February 01, 2007

Security Measures to take into account when designing web sites

  • Always create at least two network boundaries:
    1. A DMZ (i.e. Front-end machine area)
      • Web servers mainly, but it could have other machines used for communication, as long as:
        • No customer data should be hold in this network boundary
        • Machines in this boundary can only talk to machine on the next level down if that machine does not hold any confidential data (e.g. Customer Data, Partners data, Employees data, etc..)
    2. A Back-end machine area
      • Application servers
      • Database servers containing confidential data migh be here (or a third boundary network could host them)
      • Intranet web servers
      • dqw
  • A firewall must exits:
    • In front of the DMZ
    • Between the DMZ and the back-end area
  • Machines in the F-E can trust machines in the B-E
  • Machines in the B-E cannot trust machines/identities from the F-E
  • If an Employee or Partner Web site must be available from the Internet area, it must be in a different DMZ (if possible).
  • It is always a good thing to have two URLs for a web site:
    1. http://www.mysite.com/ for normal browsing (port 80)
    2. https://secure.mysite.com/ for secure browsing (port 443)
      • This enables HTTPS to be handled by hardware
      • The Encryption traffic will happen between the client’s browser and the public firewall in front of the DMZ
      • In the DMZ, the HTTP request can be handled by the normal HTTP port (80). The application can still check whether this is a secure HTTP request by looking at the domain (http://www.mysite.com/ or secure.mysite.com).

Monday, January 15, 2007

HTTP Request issues – "Expect: 100-continue" and "Connection: Keep-Alive" headers


I have been working on a little .NET application (1.1) tool to send other HTTP the content from an XML file.

As I was intercepting the HTTP requests/responses going on between my machine and the server, I found out that my .NET application was always sending as part of the headers:

  • "Expect: 100-continue"
  • "Connection: Keep-Alive"

My application will always send a HTTP request in one go, get the response and exit. So, I need to get rid of those two HTTP headers (or at least disable them).

Here a sample from “TCPTrace”:
# The HTTP request


POST /HTTPFlowerServer/Cancellation.aspx HTTP/1.1
Content-Type: text/xml
Content-Length: 89
Expect: 100-continue
Connection: Keep-Alive

Host: localhost:8080

<?xml version='1.0' encoding='utf-8'?>
<MyRequest><Cancellation Id="27" /></MyRequest>


# The HTTP response


HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Mon, 15 Jan 2007 18:23:03 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=sq2f2p55jqjluojh3mr4qh3o; path=/
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 74

<MyResponse><Acknowledgement OrderId="27"></Acknowledgement></MyResponse>


In order to not keep the connection alive, you need change the “KeepAlive” property of your HttpWebRequest.

In order to remove the “Expect: 100-continue”, you need to change the settings on the ServicePoint used by your request.

Here is what you need to do:


HttpWebRequest myRequest = (HttpWebRequest)System.Net.WebRequest.CreateDefault(targetURI);
myRequest.Method = "POST";
myRequest.KeepAlive = false;
myRequest.ServicePoint.Expect100Continue = false;


I found the latter solution from a blog at http://haacked.com/archive/2004/05/15/449.aspx. Look for the entry made by Mirronelli.

Here a sample of the HTTP headers after the changes:

# The HTTP request


POST /HTTPFlowerServer/Cancellation.aspx HTTP/1.1
Content-Type: text/xml
Content-Length: 89
Connection: Close
Host: localhost:8080

<?xml version='1.0' encoding='utf-8'?> <MyRequest><Cancellation Id="27" /></MyRequest>

# The HTTP response


HTTP/1.1 200 OK
Connection: close
Date: Mon, 15 Jan 2007 19:00:53 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=npxysrbhbz4rsi455x5qhe45; path=/
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 74

<MyResponse><Acknowledgement OrderId="27"></Acknowledgement></MyResponse>

Wednesday, August 02, 2006

IIS - Web issue - "Global.asax could not be loaded"

(I had this issue back on 10 April 2006)

This blog is to raise awareness of new security features in Windows SP SP2 and 2003 SP1 which are not always very visible through the different tools (e.g. Internet Explorer, Windows Explorer, ...), but can make applications fail silently without warnings or events being logged.

My sources and references I used to resolve this issue are below:

  • The main technical concept to be aware of is "Fork in file systems". A fork in a file system is used to add extra data about a file system object (metadata, different format,...) See http://en.wikipedia.org/wiki/Alternate_data_stream

  • The "fork" feature in NTFS is known as "Alternate Data Stream" (ADS). This feature has been a part of NTFS since the beginning.

    • With Windows 2000, ADS was used to stored extra information such as "Author", "Thumbnail" picture, ...

    • With Windows XP SP2 and Windows 2003 SP1, Microsoft introduced the "Attachment Execution Service" to store details on files that have been downloaded. This information is sometimes referred to as "Evidence". The ADS used by "Attachment Execution Service" is called "Zone.Identifier" (I am not sure whether there are any more).



The other key point to be aware of is that not everything in Windows XP SP2 or 2003 SP1 is performing this security access check.For example, Windows Explorer implements the check against the ADS "Zone.Identifier". Whereas, the command line (i.e. cmd.exe) does not. Because the Windows Kernel module loader does not implement this check, the new security feature is bypassed when using the command line to execute applications.

The original issue
On the web servers in my environment, some Web application pools (Books, Entertainment,...) were (sometimes) unable to instantiate a Web Application object because it could not load the type defined in "Global.asax" and implemented in a code-behind assembly in the \bin folder.

The causes
This was due to the fact that:

  • All machines in my environment have been rebuilt with Windows 2003 SP1. A lot of features in SP1 are related to security.

  • Assemblies (mainly DLLs) in the \bin folder for some of the Web applications were marked as "Blocked".

  • DLLs were marked as blocked, because the unzip process was done remotely (i.e. one computer was running the unzip algorithm and saving the files via a map drive to another computer). Because these files were "downloaded" through the map drive, Windows marked them as "Blocked" by setting the metadata in the "Zone.Identifier" stream.


The Solution
Using Windows Explorer, check the properties of the file and "Unblock" the file if necessary (there is an 'Unblock' button).It would be good to have a tool that could scan folders and "unblock" DLLs/Exe's.
On the Internet, there are quite a few tools to list "Alternate Data Stream" attached to files, but I have not yet found one from or supported by Microsoft. If anyone knows of any tools, please let me know.

Tuesday, June 13, 2006

Robert Scoble is leaving Microsoft / PodTech

(From Reuters news - http://go.reuters.com/newsArticle.jhtml?type=technologyNews&storyID=12494144&src=eDialog/GetContent)

The world's most famous corporate blogger, Robert Scoble, credited with helping to break down a siege mentality at his employer, Microsoft Corp., confirmed on Sunday he is leaving to join a recently formed Silicon Valley Internet media start-up (
http://scobleizer.wordpress.com/).

Scoble's offers succinct advice to other corporate bloggers who wish to keep their day jobs: "Understand your company's culture before you start mouthing off. When you start breaking the rules, you better know you are breaking the rules."

Thursday, May 04, 2006

BizTalk SQL Receive Adapter - where to host it?

Currently, I am working on a BizTalk Server 2006 solution and I came across an interesting point about how a SQL receive adapter should be hosted.

Bytheway, I am not the only one with this scenario ; Richard Seroter posted the same issue on his blog, "BizTalk SQL Adapter Advice Requested" (
http://blogs.msdn.com/richardbpi/archive/2005/11/22/496020.aspx) .

So, the scenario involves at least two physical servers, each one hosting the same biztalk host, e.g. "host1". Host1 host many things, and in our case it is the one hosting a SQL receive adapter, e.g. SQL_R1.

The main function of SQL_R1 is to call a stored procedure on a production database, see whether or not there is any work to be picked up. If there is some, then it returns the TOP 10 records (or whatever), and set a flag. All of this is happening inside a distributed transaction (assuming that the production DB is on a different server than the BizTalk MessageBox DB):


- Our production table is enlisted in that transaction
- The BizTalk messagebox which will receive the message is also enlisted in that transaction

Under some circunstances (e.g. loads), a concurrency issue arises: one of the instance of SQL_R1 will have its transaction process terminated by the Resource manager on the production DB server (this is due to lock issues). Ok. this might raise some warnings on the BizTalk server hosting that SQL_R1 which had the error, but the real issue is that after a number of errors raised on the receive location for SQL_R1, Biztalk will disable that receive location and both instance of SQL_R1 will stop running.

At the moment, the solution I implemented is as follow:

- Create a new host to host the SQL receive adpater.
- Create two host instance (in-process) - one per server (set "do not start" on one of the server).
- Allow the SQL adpter's receive function to be hosted by the new host.
- Change the setting of the SQL_R1 in my Application to use the new "receive handler host".

Pros and Cons:
+ we do not have anymore the SQL recieve adapter disabled by BizTalk (the transaction is not anymore terminated)
- We have lost the "automatic failover" facility on the SQL receive adapter. Now, when the server hosting SQL_R1 is down, we need manually to start the second host instance for SQL_R1 on the second BizTalk server.

I will carry on searching for other solution/implementation for this scenario.

Wednesday, May 03, 2006

Agile Project Management - Chickens and Pigs

I found an interesting blog from Tamer Shaaban's on "Using Agile Project Management with Integration Projects":

http://blogs.conchango.com/tamershaaban/archive/2006/03/01/3017.aspx .

Friday, September 23, 2005

The 'Escape()' error

It took me quite a while to find out what was going with this error. With the help of Arturo, we cracked it down. Thanks Arturo!

In our boxes, we were experiencing problems with Microsoft Visual Basic Script: could not find a variable called 'Escape()'. In fact, Escape is not a variable but a Vbscript function introduced as part of VBScript version 5.0 .

The main reason it was not working was because we had registered an old version of the vbscript engine in our machines by mistake.

The normal location for the dll is: \System32\vbscript.dll .

One way to check whether you have got the right version is look into the registry for this UUIDs and check for their Inproc32 subkey:

ClassIDs:
---------
{3F4DACA4-160D-11D2-A8E9-00104B365C9F} - VBScript Regular Expression{B54F3741-5B07-11cf-A4B0-00AA004A55E8} - VB Script Language{B54F3742-5B07-11cf-A4B0-00AA004A55E8} - VB Script Language Authoring{B54F3743-5B07-11cf-A4B0-00AA004A55E8} - VBScript Language Encoding

LibIds:
-------
{3EEF9758-35FC-11D1-8CE4-00C04FC2B185} - Microsoft VBScript Global{3F4DACA7-160D-11D2-A8E9-00104B365C9F} - Microsoft VBScript Regular Expressions

To fix it, we just needed to register the right version of the vbscript engine dll, i.e. usually the one in System32 folder.
In a command line window, go to the \System32 folder and type in the following comamnd:
>regsvr32 vbscript.dll

Thursday, August 11, 2005

How to release unmanaged resources in .NET

# Global tip / Remarks


a] when developing using a managed platform such as .NET, DO remember that the garbage collector only regains MEMORY resources from managed objects. It is up to you to close and release other resources (COM/COM+ objects, files, network connection, DB connection /data reader, ...), the sooner the better.



b] Not all unmanaged resources can be released/free using the same method. Most of them implements the interface System.IDisposable but it is not mandatory, just good practice. Read the documentation to find out.



c] Usually a class which inherits from System.MarshalByRefObject will implements IDisposable or have some private mechanism to release unmanaged resources. This is a rule of thumb and is not always true, but enough to pay attention to it and read the documentation about the .NET class.



d] In order to use the C# construct "using" the type you want to instantiate must have a Dispose() method. It can do so by implementing the interface System.IDisposable but it is not mandatory.



# COM objects (.NET class exposed to COM or Legacy code exposed via COM, e.g. VB code)


- They tend to inherit from System.MarshalByRefObject, but is not mandatory.


- Examples of such things are when you use COM Interops in your .NET code.


- You should release the reference to a COM interface by using ReleaseComObject() as shown below:


BasketClass voucherBasket = null;
try
{


voucherBasket = new BasketClass();


... IF YOU NEED TO USE ANOTHER COM class, DO ANOTHER try/finally BLOCK INSIDE


... DO NOT SET voucherBasket to "null" IN THE try BLOCK, UNLESS IF CALL ReleaseComObject AS WELL
}
... catches if needed
finally
{
if (
voucherBasket != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject( voucherBasket );
}
}



- Another variant of this is the following


BasketClass voucherBasket = null;

voucherBasket = new BasketClass(); // MAKE SURE YOU HAVE ANOTHER try/finally BLOCK TO CATCH ANY EXCEPTION DURING INSTANTIATION

try
{

... IF YOU NEED TO USE ANOTHER COM class, DO ANOTHER try/finally BLOCK INSIDE

}
... catches if needed
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject( voucherBasket );
}


# COM+ objects (.NET class exposed to COM+ by inheriting from ServicedComponent)


- All .NET classes which want to benefits from COM+ Enterprise Services must inherit from System.EnterpriseServices.ServicedComponent (which along the line implements IDisposable).

- You should use the "Dispose pattern".

using(Tesco.Common.Operations.CustomerOperations customerOperation = new Tesco.Common.Operations.CustomerOperations())
{

... DO WHATEVER YOU NEED TO DO ...

... IF YOU NEED TO USE ANOTHER SERVICEDCOMPONENT, DO ANOTHER using BLOCK INSIDE...

}

# COM+ objects (Legacy code exposed via COM+, e.g. VB code)

- You interop with such objects the same way as for COM objects (=> COM Interops).

- They do not implements IDisposable interface or a Dispose() method, so you cannot use the "Dispose pattern".

- you must use "System.Runtime.InteropServices.Marshal.ReleaseComObject" as shown above for COM objects.

# Summary about COM and COM+

Client

Server

Client calls Dispose()

Client calls ReleaseComObject()

Client calls IUnknown.Release()

.NET

.NET class inheriting from

ServicedComponent

Yes

-

-

.NET

Legacy COM

or

Legacy COM+

-

Yes

-

Legacy

(VB, ASP)

.NET class inheriting from

ServicedComponent

Yes

-

Yes

Legacy

(VB, ASP)

.NET class

exposed to COM

Yes

If the .NET class implements a Dispose() method

-

Yes

# System.IO.* (e.g. Stream, TextWriter, TextReader, ...) objects

- Usually those .NET classes implements IDisposable, so you should use the "Dispose pattern"

string message = null;
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream, System.Text.Encoding.ASCII))
{
this.TransformData(xmldata, base.Xsls.ForgotPasswordEmail, null, streamWriter);

memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream, System.Text.Encoding.ASCII))
{
message = streamReader.ReadToEnd();
}
}
}

# Becareful with Properties/method/Collections returning COM/COM+ objects

- See this extract of code:

try

{

VoucherBasket voucherBasket = new VoucherBasket();

try

{

voucherBasket.Customer.GetCustomerId();

}

finally

{

ReleaseComObject(voucherBasket);

}

}

... catches if needed

finally

{

...

}

- The problem here is the "Get" property "" which returns under the cover a reference to a COM/COM+ object (i.e. a CCW, COM Callable Wrapper).

The object is not released until it gets collected by the garbage collector. When? we cannot be certain.

- Good way (assuming Customer is a legacy COM class):

try

{

VoucherBasket voucherBasket = new VoucherBasket();

try

{

Customer customer = voucherBasket.Customer;

try

{

customer.GetCustomerId();

}

finally

{

ReleaseComObject(customer);

}

}

finally

{

ReleaseComObject(voucherBasket);

}

}

... catches if needed

finally

{

...

}

# Further Readings

- Enterprise Services FAQ

- .NET Framework Resource Management