Edit .svcmap file to access "hidden" functions of service references
01 August 08 10:40 AM | Lifeng Lu | 0 Comments   

Not all code generation options of service references are exposed through its UI.  To prevent users to be confused by some advanced options, the configuration dialog is designed to only expose options which are most likely to be used.  We can only access other options by editing the .svcmap file.  Unfortunately, the file is hidden by default, so people won't discover it easily, and most people will prevent to edit hidden files as well to prevent corrupting the project by accident.

Well, this .svcmap file is editable, and Xml Intellisense actually works here, so changing it is not that difficult.  Certainly, we are not interested to change those options which can be changed easily through the configuration dialog.  Here are something you can do with editing this file, but otherwise not doable:

1, You can enable sharing service contract types:

   by adding ServiceContractMapping in the ServiceContractMappings section, you will force the code generator to use a shared service contract type defined in a referenced assembly (you cannot share a type defined in the current project.)  The service reference will still generate configuration to the app.config file.

2, you can define complex collection mappings:

  the configuration dialog only support some limited options. Adding CollectionMapping in the file, you get similar function you can get by using svcutil command line.

3, namespace mappings:

  it works like /namespace option in the svcutil command line

4, you can add additional MatadataSources!

  actually, you can reference two services in one service reference, and share the data types. Adding additional MetadataSource to the file by hand is the only way to do that today.  Once you added, it will be maintained, and it will not be lost, when you update the service. (Actually, you don't need add MetadataFiles by hand.  Just add a MetadataSource into the file, save it, and Update the reference, all metadata files will be downloaded automatically.

5, add additional Metadata files

  It is possible to add additional metadata files to a service reference, just copy them to the folder, and add additional MetadataFile node in the .svcmap file to reference them.  They will be used in the code generator.  All MetadataFile without a SourceId will not be automatically updated, so they will stay even when you update the service reference.

6, add private configuration file

 You can add a special extension file with name = "Reference.config" (very similar to configuration.svcinfo).  With the configuration file, you can add additional extensions to the code generator. (Unlike adding them to the machine level configuration, things in the Reference.config only affect the code generator in one reference.  Special security settings to enable downloading metadata files from a secured server is also possible through a such config file.

7, additional extension files

  The additional code generator extensions can locate those extensions file registed in the Extension section. It is possible to set additional options through those files.

 

Filed under: ,
old Schema designer and data grid editor
24 August 07 04:39 PM | Lifeng Lu | 0 Comments   

Two old designers in VS 2005 have been removed from Orcas product.  There are several reasons why they are removed:

1, there will be a brand new schema designer built into VS.  However, because of schedule issues, it is not in Orcas, but will be released off-cycle;

2, the two old designers depend on some old components of HTML designer.  In Orcas, the HTML designer is replaced, and those components are gone/replaced.  It becomes too costly to maintain them, especially when a new designer comes out soon.

3, the old schema designer also depend on a designer surface implemented in an old COM package, which is about to be removed.

Currently, there is no plan to build a new data grid editor, which view/edit an XML file in a data grid.  The old designer only targets data set files, and it is very limited.  It will be interesting to see whether people need it before spending time on it.

 

Side by side comparsion between svcutil and the service reference in VS
13 August 07 04:47 PM | Lifeng Lu | 0 Comments   

The Service Reference is new feature added into VS Orcas, so we don't have to use svcutil when using VS IDE.  Here is the side by side comparsion table between svcutil and the service reference in Orcas:

Svcutil command line

VS service reference (.svcmap)

VS UI

/out

(always delivery from the name of .svcmap)

 

/config

(always the config file of the project)

 

/mergeConfig

Always true

 

/noConfig

Not supported

 

/dataContractOnly

Not supported

 

/language

Always based on the project

 

/namespace

<NamespaceMappings>

But *-> ReferenceName is always added

 

/messageContract

<GenerateMessageContracts>

Yes

/enableDataBinding

<EnableDataBinding>

 

/serializable

<GenerateSerializableTypes>

 

/async

<GenerateAsynchronousMethods>

Yes

/internal

<GenerateInternalTypes>

Yes

/reference

<ReferenceAllAssemblies>

<ReferencedAssemblies>

<ReferencedDataContractTypes>

<ServiceContractMappings>

Can pick up existing reference assemblies of the project automatically

Limited

/collectionType

<CollectionMappings>

Limited

/excludeType

<ExcludedTypes>

 

/noStdLib

Through <ReferencedAssemblies>

Yes

/serializer

<Serializer>

 

/importXmlTypes

<ImportXmlTypes>

 

/targetClientVersion

Based on the project

 

/t:metadata

Not supported

 

/validation

Not supported

 

/t:xmlSerializer

Not supported

 

Multiple url/file

<MetadataSources>

 

/svcutilConfig

<ExtensionFile Name=”Reference.config” />

 

 Essentially, the svcutil is built for several tasks like exporting metadata, validating the service.  But the service reference is built for generating proxy/configuration only.  However, in the proxy/configuration generating scenario, the function of the service reference and svcutil are overlapped.  The service reference supports most options svcutil supports in its command line.  However, to access those options, editing the .svcmap file is necessary  (only limited options are exposed through UI.)  By saving the options in a file, however, it is easier to repeat the process, when the service is updated.

 

 The advantage to use the service reference is clear when using the IDE.  We don't lose most ablility of the svcutil tool, but gain some convenience: options like the language/targetPlatform don't have to be chose again, but will be picked up from the project system automatically.  The result config is also automatically merged, and previous injected configuration will be tracked, and removed when the reference is removed or updated, so it won't inject lots of duplicated items. (That function is limited in this version if binding in the configuration is editted.)  The IDE also supports better experience when the service is secured.

 

 

Filed under: ,
How to generate Begin/End invocation pattern methods in web service proxies in VS 8+
08 August 07 04:47 PM | Lifeng Lu | 0 Comments   

It is a problem asked by some customers.  They were using Begin/End invocation pattern to call web service asynchronously.  Those async methods were generated in web proxies in Visual Studio 7.x, and when they are using wsdl.exe tool, but were gone when they use the Visual Studio 2005 or Orcas Beta 2.  In both VS 2005 and Orcas, the generated proxy only contains event-driven programming pattern methods.

First, for who is using the event-driven model, there is no reason to turn on the Begin/End pattern methods, because only one of them should be used.  For many users, the event-driven model is also easier to use.

For those who still need use the Begin/End pattern methods, it is still possible to turn on a project level option to get them back:

To do that, we need unload the project from VS, and edit the project file directly in an editor. (Please backup one in case we do something wrong.)

In the first section of PropertyGroup, you will see many properties like:
<ProjectGuid>{F4DC6946-F07E-4812-818A-xxxxxxxx}</ProjectGuid>
<OutputType>Exe</OutputType>
...
Don't change any of those, but do add an extra property just like the OutputType into that section like:
<WebReference_EnableLegacyEventingModel>true</WebReference_EnableLegacyEventingModel>
Ignore the warning from the xml editor, save the file, and reload the project into VS.

After that, you have to regenate all proxy code (by updating the reference, or running the custom tool on the .map file)

Note: it is only for old web reference proxies.  For old service references (WCF proxies), the Begin/End pattern async methods will be generated when "Generate async method" is turned on for that reference. (That is beta 2 feature.)  The methods for another pattern (event model) will not be generated in beta 2, but will be added in RTM when the project is targetting the new 3.5 framework.

 

Filed under: ,
WCF tool extensiblity samples have shipped
02 August 07 11:35 AM | Lifeng Lu | 3 Comments   

The WCF tool in the Visual Studio exposes several layers of extensibility APIs.  Those were built into the product to make a third party could extend the feature to make it easy to use in their special environment, or make the feature work in a third party environment.

Those extensibility points include:

1, a set of VSIP APIs to allow third party feature to list and manipulate WCF references inside a project;

2, allow a third party project system to enable/disable the feature, and how to store the information in the project system;

3, a way to extend the current “add service reference” dialog to help finding services;

4, support and extend standard WCF extensibility model, including support WSDL/Policy importer extensions, and allow extra settings of the extensions to be persisted in the reference.

Those new samples could be found at http://www.microsoft.com/downloads/details.aspx?FamilyID=d9000e2c-bd3f-4717-a181-723960814e16&displaylang=en

 

Passing DataTable across web/wcf services
01 August 07 01:46 PM | Lifeng Lu | 0 Comments   

Passing DataTable (without embeded into a dataset) across web services is supported in .Net 2.0 framework.  However we found a bug in this area, which might affect using this feature with strong typed dataTable.  For example, when a web service function wants to return a DataTable to the client, an independent dataTable (a dataTable which is not a part of a dataset) will work, but a dataTable inside a dataSet won't work.  What happens is that the client side couldn't deserialize the dataTable from wire.  The root reason is the DataTable inside a dataset inherits a schema namespace from the dataSet, but an independent datatable has an empty namespace (unless we change it).  Data cannot be changed between two dataTables with different namespace.

The problem is that the instance of the dataTable on the client side is created by framework directly. It is impossible to change the namespace without changing generated strong type dataset code.  To work around this issue, the server side need copy data to an independent dataTable before passing it to the client.

That affects both .Net 2.0 web services and 3.0 Windows communication fundation services.

 

Filed under: ,
Add an old (8.0) style web reference into an Orcas (VS 9) project
20 June 07 06:17 PM | Lifeng Lu | 0 Comments   

In VS 9, the "Add Web Reference" menu command was "replaced" by "Add Service Reference" command in all client projects (VB/C#) targeting 3.x platform.  Although "service reference" works for most existing web servers, the proxy generated from "Service Reference" and the old "Web Reference" is very different.  The service reference is actually a new WCF client, which gives us a lots of flexibility through its configuration system.  However, it is fairly different from the old Web Reference API, and the old code consuming old reference certainly will not work without extra work.  And there is a tricky part when we use a WCF client to consume an old web reference:  the WCF expects you to define types with new DataContract format, and most type defined in web reference is XmlSerialiable types.  The proxy generator might not work well with the default options, and sometime, we have to adjust some options to make it to work. (Often the "Auto" serializer doesn't work, and we might have to use "XmlSerializer".  Unfortunately, that option is not exposed through an UI dialog, so we have to edit the .svcmap file directly)

We might want to continue using old style web reference for those web services.  Unfortunately, "Add Web Reference" menu is disabled by default in the projects, unless you already had such reference in the project.  In beta 1, there is no way to find this command.  We have to downgrade the project to target 2.0 platform to add one web reference and upgrade the project again to add the first web reference.  It is very ugly workaround.  In CTPs after beta 1, the command can be accessed through the dialog popping up when we click the "advance" button on the "Add Service Reference" dialog.  It is not an obvious place to find it, but the menu should be enabled after that, so it only need be done once.

 

.svcmap file
15 June 07 04:08 PM | Lifeng Lu | 0 Comments   

After we add a WCF service reference into a Visual Studio project, a .svcmap file will be added to the project, and it contains most information of the service reference. Actually, it is the only essential file of the reference. In most case, we can remove all other files in the service reference, and still can pull down all the files from services by updating the service reference.  By default the .svcmap file is hidden in the solution explorer unless we turn on "show all files..." option.

Do I need understand the .svcmap file?  No, you don't have to, if you just want to play with the new WCF feature, just like you don't have to know much about command line options of the svcutil tool before you start to use that.  Actually, the file contains options for the proxy code generator, makes it equlivent to those command line options in many cases.  However, when we need deal with some slightly complex scenarios, like consuming an old web services, sometimes without turning those options, we don't get useful proxy code.  That is when we need look into this file.

Some common code generator options are exposed through a "service reference settings" dialog (not in beta1).  But many of them are not exposed through any UI.  To change those options, we will have to open and edit the .svcmap file inside a service. Fortunatly, the format of the file is fairly simple, and the schema of that file is shipped with the Visual Studio, so the Xml Editor will provide intellisense when we edit the file.

Although the most options in the .svcmap file works exactly the same way as command line options of svcutil tool, there is some difference between them.  For example, when you turn on type sharing in existing assemblies, the svcutil will share service contract types as well as data contract types.  But the code generator in VS will only share data contract types.  Service contract types will not be shared automatically.  A white list must be added in the .svcmap file to make service contract type sharing to work.

Other than the code generator options, there are some interesting things we can do when we edit the file directly.  One sample is that there is a MetadataSource section in the file, which contains where to download metadata file. By default, there is always one MetadataSource when the service reference is created through UI. It doesn't have to be this way.  For example, if the metadata is not exposed by the service, but you get them through other way of communication, like through an email.  We can copy all metadata files into the service reference folder, and reference them directly in the .svcmap file, and delete all MetadataSources.  The result will be a service reference, which generates valid code, but will not try to download files from a server.  Another possible is to add two sources, so the metadata will be pulled into one reference, and code will be generated together.  It is similar like providing two URLs in the svcutil tool.

We can also apply things similar to '/toolconfig' in the svcutil command line. That will allow us to add/remove WSDL/Policy importer extensions.  The easiest way is to add those tool configuration in the web.config/app.config of the project.  However, that solution has two problems.  First, we usually don't want to ship those design time options in the product.  The web.config/app.config is a part of the product, so we do mix the design thing and runtime thing in the same place.  Second, if we have two service references, and we want different importer extensions for them, there is no way to do so.  Fortunately, it is possible to give every service reference a seperated tool config file.  The way to do this is to add a Reference.config file in the service reference folder, and reference that file as an extension file in the .svcmap file, just like how .svcinfo file is referenced.

 

Filed under: ,
Type sharing in WCF service reference
09 May 07 12:02 PM | Lifeng Lu | 4 Comments   

Type sharing is very useful when we want to pass same data between two services.  Without type sharing, we will get seperated types in the proxy for every service we consume.  That means a lot of code to convert data in one type to another before and after calling a service, which could be painful, and unnecessary coupling in code.

For service reference, there are two kind of type sharing:

1, reuse type pre-defined in a class library in proxy code  (do not generate new type in proxy)

2, share type between services (generate new type only once for different services)

The SDK tool svcutil supports the first kind of type sharing.  The WCF feature in the Visual Studio provides same level support for this kind of type sharing.  However, it becomes easier to use, because the generator in VS could automatically extra types in depedent assemblies of the project.  We do need remember to add reference to the assembly containing pre-defined types, but don't have to pass it as a parameter as we use svcutil.  The feature in VS also provides more refined control to the user, so it is possible to share types in a small set of assemblies or disable it.

The type sharing is actually done by the DataContract importer extension, so the type sharing in VS inherits the same limitation of the feature in svcutil.exe.  Basically, if you are only using new DataContract in service contracts, it works well.  But it doesn't support sharing some xml serializable types.  Sharing dataSet is supported, but somewhat limited.  The problem is that the data set type must be defined in exactly same CLR namespace in both server and client before the type sharing can work.  It should not be a problem if we want to share a same data set between client and server, but could be a problem if we only want to share the type between clients.  Of course, since data contract types are generated by extensions, it is possible to improve that by adding new or customized extensions.

One limitation which could not be resolved by adding extension is that the shared type must be defined in a library, but can not be defined in the same project consuming the service.  Considering that the type must be used by the proxy generator, and the proxy is a part of the project.  Reusing type in the same project could somehow cause a recursive logic in the current way how the generator works today. We may have to live with that limitation.

The second style of type sharing is supported by wsdl.exe.  svcutil.exe also allows to have two metadata source URL in its command line, although it works only if there is no conflict in metadata from the two sources.  That works if the wsdl files are hand crafted, but doesn't work well when the metadata is generated automatically, because we often get duplicated schema files from difference sources.  The WCF consumption feature in VS works in a very similar way as svcutil, although it would try to remove duplicated schemas.

(BTW, the type sharing is not supported in beta 1, but CTPs after that)

 

 

ContextSwitchDeadlock MDA and COM
09 May 07 10:27 AM | Lifeng Lu | 1 Comments   

The ContextSwitchDeadlock MDA is a very annoying debugger message.  The message is reported by a background thread, which wakes up once a while and if it finds a remote call doesn't pass in 60 seconds, it raises the error.  But the problem is that the error message contains a few context code, but doesn't tell you the exactly location it happens, or tell you which thread makes the call.

Based on the document, the problem happens, when a thread (so often the main UI thread) is working on something and doesn't pump message for 60 seconds.  In that period, if a background thread tries to make a remote call to the thread, it could be blocked for more than 60 seconds, and the problem will be raised.  If the application uses COM, (maybe directly or indirectly -- for example one control is built this way), it could be a problem.  Even the application doesn't use multi thread directly, and we don't feel that we make any remote call.   The problem is that most managed application depends on the GC to release COM marshalling object,  and the GC is running in a background thread and it could run at any time.  So, when the GC tries to release a COM object when it finds no one is using that, it will make a call to the STA thread.  If the STA thread ever does something longer than 60 seconds, it becomes a problem.

It could be worse, if we create a background STA thread.  It is almost impossible to stop that thread, because if GC hasn't cleaned up all COM objects created in that STA thread at that point.  It would end up in the ContextSwitchDeadlock, because no way to call into a dead thread.  Of course, we couldn't control GC to clean up those objects before we stop the thread. Unless you can control the life of those ReleaseComObject, it is better to create MTA background thread instead.

ReleaseComObject itself could be a nightmare.  Unless you own the both side, the code could be broken easily if the COM object written in native code is updated to managed later.  The internal count is increased in any native-managed boundary, so we need know the exactly boundary, which is not really detectable in code.  'IsComObject' does not provide much value, because an object could be implemented in half managed and half native code.  For those objects, IsComObject will return true, although the call doesn't go through native/managed boundary.  Or even the half managed half native object is passed through a such boundary, its internal count never increases. The first time when you call ReleaseComObject, the native half of the object will be released, and the whole thing is now broken.

 

 

Files in a service (WCF) references
08 May 07 04:32 PM | Lifeng Lu | 0 Comments   

The new service reference is persisted in a similar way how the old web reference is persisted in a visual studio project.  All files including metadata file downloaded from the server will be persisted into a single folder, which defines the CLR namespace proxy code lives in.

Files in a service reference is not shown in the solution explorer by default, but it is easy to see them by turning on "Show All Files".

Those metadata file includes all WSDL and XSD files.  DISCO files will be also kept, if the metadata is downloaded from a disco port, although those disco files are never used in configuration/proxy generation.

All those metadata files and code generator operations are persisted in a .svcmap file.  The .svcmap file is the basic unit for the proxy/configuration generator.  We may add multiple metadata sources into one .svcmap file, so the code generator will handle them at the same time.  If the metadata is property prepared, the code generator will generate shared data contracts for multiple service contracts.  This is just one function that you have to get by editing the .svcmap file directly, because it is not exposed through simplified UI.

Besides the .svcmap file, there is a '.svcinfo' file which tracks the configuration added to the app.config/web.config, so that portion can be removed when the service reference is removed from the project.  When we update the reference after the service is updated, we will try to update the app.config file, but not just inject another section of configuration into the file, like what svcutil did.  The format of this file is not designed to read/edit by human, it is better not to mess up this file.

However, currently, the fuction to maintain the app.config is faily weak.  It is certainly better than svcutil, with which you have to maintain the file by yourself. But while the function works fine when you live with the configuration generated automatically, it doesn't work well after you change it.  In most case, it will not take out the configuration changed by you, but will inject the new section side by side with it.  That makes that function less useful in those advanced scenarios.

There are talks about what to do when the injected configuration has been updated, but the extensibility of the configuration in WCF makes it more complex than what can be done in a short product cycle.

.svcinfo file is persisted as one extension file of the .svcmap file. The .svcmap file allows other customized extension files, so actually a customized WSDL importer/policy importer extensions could pick up options from one extension files to control options in code generator. BTW, just like svcutil, those importer extensions are supported in VS.  Without the toolconfig parameter, you need add those extensions in the machine.config or app.config of the project.  The drawback to put those design time configuration into app.config is that you would leak them into the runtime.  In beta 2, it is possible to put those design time configuration in a seperated config file.

So, an advanced user could write an extension to change generated configurations by changing certain values, or remove not needed ports.  It could be done in a general way, and its real behavior can be controlled by an extension file, which could sepecify like which port need be removed, and what binding parameter need be changed, so you don't have to manage the app.config file by hand.

 

Filed under:
Windows communication framework client in web site projects
26 April 07 11:09 AM | Lifeng Lu | 0 Comments   

The Visual Studio Orcas beta1 supports generating and using WCF client in the ASP.Net web site projects.  From the platform point of view, ASP.Net wants to enable an user to build a web site without any Visual Studio tools. The feature to generate WCF client has been built with the same sprit.  With Visual studio, you can easily add a WCF client, but without it, you can create your own by creating a 'svcmap' file.  The 'svcmap' file will be processed by a build provider at the runtime to generate WCF client code, which will be compiled on the fly, so web site code could consume those classes.

However, that comes with a price.  Because the build provider hasn't been built into the 3.0 framework (it is added in 3.5 framework), so it becomes not possible to consume WCF this way in a project targetting 3.0 framework.  That is why we can create a WCF server with a 3.0 project, but couldn't consume it in the same project.  (Of couse, if you use svcutil tool, it is still valid to generate WCF client, and consume it in a 3.0 web site project.  But you have to do everything by hand.)

However, a build provider might work well to do some simple code generation.  It actually is not a good platform to geneate complex proxy code.  The problem is that it can either sucess without any message, or fail with one message string, so it becomes no way to output waring messages, if anything might be wrong.  That is why it could be difficult to figure out a problem in the WCF client in a web site project.  Using a web application project might be a better choice, or maybe I will add the same WCF client to a client project to see warning messages.

The svcmap file is also used in the client project, so it is actually easy to copy one from a client project to a web site project.  Metadata files pulled down from services are saved in individular xsd/wsdl files, and actually referenced by the svcmap file.  It is somewhat similar to the discomap file in a web reference in VS 8.  The svcmap file also contains code generation options.  Many options of the svcutil tool are supported.  However, those options are not supported in the beta 1 product.  Unlike the old web reference, default proxy works fine in most cases.  Sometime, it is necessary to adjust those WCF client options to get right proxy code, that is especially true when you consume a service built with old web service platform.

 

Filed under: ,
Where is "Add Web Reference" after I install Orcas Beta 1
24 April 07 10:30 AM | Lifeng Lu | 0 Comments   

When you create a project targetting .Net framework 3.x in Orcas Beta 1, the "Add Web Reference..." menu is replaced by "Add Service Reference..." menu.  "Add Service Reference..." will create a WCF (Windows Communication Framework) client to a web service.  The proxy generated by WCF is very different from old web reference proxy.  You can consume old web reference through new WCF client.

 The WCF client is not supported when your project is targetting .Net Framework 2.0. You are still able to add old web reference to those projects.  When you upgrade a 2.0 project to 3.x, if your project contains any old web reference, you will still be able to add extra old web reference.  In that case, both "add web reference..." and "add service reference..." will be shown.

So if you do need add old web reference to a project targetting 3.x framework, the workaround is that you can change the targetFramework to 2.0, add one web reference and change back the target framework.

BTW, in Orcas beta 2, you will be able to add Web Reference to 3.x projects.

 

Filed under: ,
Using XmlSerializer with internal classes
28 September 06 09:58 AM | Lifeng Lu | 0 Comments   

Normally, it is not possible to use XmlSerializer with internal classes.  However, it is possible to work around this issue, when the internal classes are written in C#.  

To do that, we need create a special build configuration, and '#if' block in the code to build a version of assembly, where those internal classes are public. (The result assembly is only used in the workaround, and could be discarded after that.)  Once we get this assembly, we can use sgen.exe in the framework to generate a serialization assembly for this assembly (with public classes.)  We need use command line option '/keep' when we do this. That option will leave the C# source code in the directory. However, the tool pick up a random name for this code file, so it is better to do this in an empty directory.  Once we get this C# code file, we will include it in the original project.  Because those generated classes have been built into the assembly, they can access internal classes correctly.  It is necessary to edit the generated code a little bit to remove assembly attribute, change the namespace of those classes to whatever we want, and maybe change the generated classes to internal as well.

We need change the code where XmlSerializer is created to use the generated Serializer. It is actually easier to use. With pre-generated code, it is also faster.  However, it is a problem to maintain the generated code up to date. We have to regenerate the code when the change in those classes impacts the serializer.  It is possible to do some scripting to make the whole process done automatically.

 

 

How to make generated resource class public
16 March 06 05:17 PM | Lifeng Lu | 9 Comments   

If you create managed application in Visual Studio 2005, you will notice that a resource class is generated when you add resources to the resx file. The class makes getting resource values much easier.  But some are troubled because the class is generated as Internal, which blocks you to access it in another assembly.  For people who create one assembly specially for resources, it could be a problem.

It is a limitation of the current code generator within VS.  However, the command line tool resgen.exe (in the Framework SDK) does support you to create a public class from your resource file.

We want to do is to disable the default code generator in the VS. To do that, we need show all hidden files in the solution explorer (from the toolbar). Select the resx file, and clear the "Custom Tool" property of this item.  However, if we are using VB, for the default resource.resx under "My Project", the resource designer will add "Custom Tool" back when we open it.  We would have to create a new resource file to the project, and do not use the default resource file.

Now, after editing the resx file, we can bring up a command window, and run the resgen.exe with property option, we will get the generated code, and of course, need to add it to the project.  It will be pain to do that everytime you edit the file.  However, we can put this in the project file, so it will be done automatically when we build the project.

Just save the project, and open the project file in notepad. Edit the file carefully (and backup one in case we mess it up.)  Just add those to project file (It is a sample with csproj, we need change some for VB):

  <Target Name="BeforeBuild" DependsOnTargets="CreateStrongTypeResource"/>
  <Target Name="CreateStrongTypeResource" DependsOnTargets="GenStrongTypeResource" >
    <CreateItem Include="Properties\Resources.cs">
      <Output TaskParameter="Include" ItemName="Compile" />
    </CreateItem>
  </Target>
  <Target Name="GenStrongTypeResource" Inputs="Properties\Resources.resx" Outputs="Properties\Resources.cs">
        <GetFrameworkSdkPath>
            <Output
                TaskParameter="Path"
                PropertyName="SdkPath" />
        </GetFrameworkSdkPath>
   <Exec Command="&quot;$(SdkPath)\bin\resGen.exe&quot; /str:c# /publicClass Properties\Resources.resx"/>
  </Target>

Save the csproj file, and reload it in the Visual Studio. Now, we can change the resx file with the new resource designer in VS2005, and build it, the generated type will be built into the assembly.

 

More Posts Next page »
Page view tracker