Build Error Ambiguous Reference WCF - wcf

I am created a wcf service. Everything has been working fine. Now all of a sudden with adding any logic I am getting a build error where I am consuming the wcf service saying:
I have an Ambiguous Reference.
I can fix this by qualifiing the object as part of the service and it works fine
ServiceReference1.AccountCredit=GetSomeData()
The thing is all thee other objects on the page are referencing an objectModel dll except this one.
I went further and viewed the service reference itself in the browser and see visual studio for whatever reason on this particular object added a file containing the following:
<?xml version="1.0" encoding="utf-8" ?>
- <!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
- <GenericObjectDataSource DisplayName="AccountCredit" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>TestMethods.ServiceReference1.AccountCredit, Service References.ServiceReference1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>
All the other objects I use dont have this and in turn this is the only object on the client that is complaining.

It may be that "MyObject" is the only name that is present in two different namespaces, where both the namespaces are referenced by a using statement at the top of the cs file.

Related

Loading config file in Class Library

I have a Class Library, which is called by a VB6 client and VB.NET client. If the Class Library is called by the VB.NET client then there are settings in the app.config for Log4Net (http://logging.apache.org/log4net/). If the library is called by the VB6 code then there is no logging at the moment.
The question I have is about the app.config. If I have an app.config in the VB.NET client (Windows Forms) and the class library, then I assume that:
If client is Windows Forms then
Use VB.NET App.config
ElseIf client is VB6 then
Use Class Library app.config
Is that correct. I have done some research on MSDN, however I cannot find anything explicit and hence the question.
I don't think class libraries support app.config files directly - they merely use the app.config / web.config of the assembly that forms the process - so the console app, service, WinForms App etc.
app.config files are useful only to CLR executable assemblies and they are automatically loaded when the application runs.
If your executable is not a managed application (application developed using VB6 I assume), app.config is useless because CLR won't get loaded into the process (since it is not a managed app).
If your assembly is managed but not executable (class library), it is useless (useless in terms of execution, otherwise it can be used to copy the contents to an executable project's app.config).
Class library uses the config file of its host, so even if the class library project has a config file, it will not be reference at run time. Instead it will look for the config file of the host executing the DLL.
To avoid recompiling the code after the build to update a variable values like Development DB and Production DB, etc. You can either use setting or hard code a path in your program to look for a 'config' file. I use an XML file, with a key-value pair. I then load and read it to a list, or dictionary that i can use in my application like a 'config' file.
Now when I deploy, I can simply change the 'config' file in the hardcoded location in my dll to whatever environment without the need to rebuild the class library.

Reference VB.NET DLL in Kofax Document Validation Script

We are working on a validation script for Kofax Capture 9.0 / 10.0 in VB.NET 3.5.
We know how to create a script using the Admin Module, and how to get it operational.
The problem is that we need to reference a dll, located on a remote machine. (GAC is no option) This dll holds abstract classes we need in each validation script.
Even when putting the dlls locally (copy local), the Validation Module (index.exe) immediately throws the "cannot find reference" exception, even though the project compiled perfectly.
I guess the basic question comes down to: where do we put the dlls, in order for the Validation Module to find them?
The simple answer is to put the dll in the same folder as the application because this is one of the places which .NET will probe when trying to find it. The Validation module is run from the Capture bin directory which will be something like "C:\Program Files (x86)\Kofax\CaptureSS\ServLib\Bin\". This would need to be done on each client using Validation.
If you have a more complicated scenario, you could look implementing the AppDomain.AssemblyResolve Event and using Assembly.LoadFile to get the assembly from a custom location, but the using the bin path is less complicated.
If you end up having further trouble, you can troubleshoot by using the Assembly Binding Log Viewer (Fuslogvw.exe) which can tell you more details about why the assembly failed to load and where .NET tried to search for it. Assembly loading can fail for reasons other than just the path.
For more detail on how .NET loads assemblies, see the following:
How the Runtime Locates Assemblies
Locating the Assembly through Codebases or Probing
We found a solution: add all library files as "links" to the project. (Add --> Existing File --> small arrow next to "Add" --> Add as Link)
This ensures the files are compiled when you build the project. The Kofax Validation Module can now find the files, whereas when referencing the file, it could not. Why it could not, remains a mystery...

App.Config - client app or class library

I have experience using the Web.Config file in ASP.NET. I am trying to add an app.config file to a VB.NET project.
I am able to retrieve a connection string in one of the classes (in the class library) if I add the app.config to the client application, but I am unable to do so if I add the app.config to the Class Library project (I get a "object is not an instance" error). What is the difference between adding the app.config to the client app and adding it to the class library?
The app.config always belongs to the executable assembly. If a library tries to read the app.config, it will be actually reading the app.config that belongs to whichever executable is using that library. That is why you can put settings in your executable's app.config which apply to various .NET framework libraries.

troubles with generating a service reference

I have to build a .Net application that consumes a bunch of web service. This web service runs under weblogic. The WSDL of the web services mention a XSD file that describes the types.
When I try to add a "Service reference" with VS studio, I have some errors :
Warning 1 Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.XmlSerializerMessageContractImporter
Error: Schema with target namespace 'http://mycustomer/ws/types' could not be found.
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://mycustomer/ws/wsdl']/wsdl:portType[#name='lbWebPT'] C:\Projects\mycustomerproject\Service References\ClientService\Reference.svcmap
X3 for the portType, Binding and port elements of the wsdl file.
I was guessing this was because of the missing types defined in the xsd file. To workaround this error, and also to avoid duplicate code, I run the following command on my xsd file (in a pre-build event command line) :
"%ProgramFiles%\Microsoft SDKs\Windows\v7.0A\bin\xsd.exe" "$(ProjectDir)xsdofmycustomer.xsd" /namespace:"MyCustomer.WebServices.Types" /c /o:"$(ProjectDir)."
this command successfully produces a code file with the types and with the correct namespace defined in the XmlRootAttribute.
this code has been put a dedicated VS project. The project where I'm trying to reference the service reference this project. However, the error is still occurring.
What can I do to solve my problem ?
PS: I was able to partially solve my problem using svcutil.exe pathtowsdl pathtoxsd, but I'd like to be able to maintain the reference in VS for ease of use.
thx
I'm not a fan of using project Service References because of the cruft the proxy generator inserts by default. But, if you really want to use Service References for your project then you need to merge the contents of the wsdl & xsd files into a single file. The Service Reference UI assumes all the data it needs to generate the proxy is in the file you give it. SvcUtil is more flexible as you found out. You should able to replace the wsdl:import element with a wsdl:types element that contains the xsd file contents (without the xml directive of course). Next, you enter the path to the file in the address textbox of the Add Service Reference dialog and you should be good to go with Visual Studio catered proxy goodness.

how can a Win32 App plugin load its DLL in its own directory

My code is a plugin for a specific Application, written in C++ using Visual Studio 8. It uses two DLL from an external provider. Unfortunately, my plugin fails to start because the DLLs are not found (I put them in the same directory as the plugin itself).
When I manually move or copy the DLLs to the host application directory, then the plugin loads fine. This moving was deemed unacceptably cumbersome for the end user, and I am looking for a way for my plugin to load its DLLs transparently. What can I do?
Relevant details:
the host Application plugins are located in a directory mandated by the host application. That directory is not in the DLL search path and I don't control it.
The plugin is itself packaged as a subdirectory of the plugin directory, holding the plugin code itself, but also any resource associated with the plugin (eg images, configuration files…). I control what's inside that subdirectory, called a "bundle", but not where it's located.
the common plugin installation idiom for that App is for the end user to copy the plugin bundle to the plugin directory.
This plugin is a port from the Macintosh version of the plugin. On the Mac there is no issue because each binary contains its own dynamic library search path, which I set as I needed to for my plugin binary. To set that on the Mac simply involves a project setting in the Xcode IDE. This is why I would hope for something similar in Visual Studio, but I could not find anything relevant. Moreover, Visual Studio's help was anything but, and neither was Google.
A possible workaround would be for my code to explicitly tell Windows where to find the DLL, but I don't know how, and in any case, since my code is not even started, it hasn't got the opportunity to do so.
As a Mac developer, I realize that I may be asking for something very elementary. If such is the case, I apologize, but I have run out of hair to pull out.
You are not asking for something very elementary. Windows simply does not support what you want.
You have some options to work around this issue:
Create two DLLs. Your plugin implementation dll, that statically links against whatever other dlls you need. And a simple "facade" dll that is loaded by the hosting app. The facade dll gets to call SetDllDirectory then LoadLibrary to load your implementation dll with the required search path, and then, for each plugin exported function, it implements a stub function that uses GetProcAddress to just pass the call straight to your implementation dll.
If the plugin interface is complicated, but the dll interface you are using is not, then:
Give up and just use LoadLibrary (with an explicit path) and GetProcAddress to access the functionality in your satellite dll(s). Pain.
The final option is the least documented and most badly understood by windows programmers. Basically we use the windows version of a technology built to support .NET: Side by Side assemblies. Don't be frightened. A "Side by Side assembly" is very simply a regular old dll, but with a accompanying .manifest file that provides some extra information about it.
The reason we want to do this is the search order for dlls that are linked in via the SxS technology is different to the regular dll search order :- Namely - after searching c:\windows\WinSxS, windows will search the same folder as the dll that references the dll, NOT the folder of the exe.
Start by taking an inventory of all the satellite dlls your plugin dll needs to link to, and create an "assembly" from them. Which means: create a .manifest file with a bunch of file= nodes. You need to give the assembly a name. Lets call it "MyAssembly".
Create the file "MyAssembly.manifest" in your dll's folder, with contents similar to the following: (listing each of the dlls you need to include)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="MyAssembly" processorArchitecture="*" type="win32" version="1.0.0.1"/>
<file name="firstrequireddll.dll"/>
<file name="2ndrequireddll.dll"/>
</assembly>
Now, thats your assembly manifest. We are half done.
The next half is to actually get your dll to use the assembly, and to do that you need to add a manifest resource to your Dll file. That manifest ultimately needs to contain the following content :-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="MyAssembly" version="1.0.0.1" processorArchitecture="*"/>
</dependentAssembly>
</dependency>
</assembly>
Apparently application manifests (which is a confusing name when embedded in a dll), are also allowed to use a <file> node, so it might be possible to skip creating an assembly, and just go with
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="firstrequireddll.dll"/>
<file name="2ndrequireddll.dll"/>
</assembly>
as the dll's manifest. I havn't toyed with that iteration yet, so Im not sure how that alters the normal dll search path (if at all).
Without knowing your development environment, its hard to know how to advise you how to add a manifest to a dll. If you are editing a .rc file and entering the manifest by hand, know that in Dlls the resource id to use is 2, not 1, which it typically used in exe examples.
If you are using DevStudio 2005 or higher, there is a handy #pragma directive that will make everything magically have the correct id's and be in the correct places.
If the project settings are on their defaults, VS2005 and up will automatically generate, and embed a manifest as appropriate. this #pragma will add additional assembly dependencies
to the generated manifest :-
#if _MSC_VER >= 1400 // VS2005 added this directive
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Company.Product.Subsystem' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"language='*'\"")
#endif
Delay loaded DLLs are your friend in this situation. I faced the exact same problem a while back and it's actually rather simple. You specify to the linker (/DELAYLOAD flag) which modules are delay-loaded and basically they modules are not listed as explicit imports in the PE header so the loader won't complain when it cannot find the said modules and all the calls to functions from those modules are wrapped in a stub which ensures the module is loaded & the function is found.
So, let's say you wished to delay load the XmlLite library. First you'd specify /DELAYLOAD:XmlLite.dll in the linker flags. Then in your module's initilization function (preferably DllMain) you'd unpack the XmlLite DLL into a temporary folder and then call LoadLibrary on it. From there on it, each call to any function exported by XmlLite.dll would be resolved automatically.
Use GetModuleFileName() to find the path where your dll is located.
Then use SetDllDirectory() to add that path to the dll search path.
Assuming native code and that you can use explicit run-time dynamic link (rather than any form of implicit link), use GetModuleHandle and GetModuleFileName to find out where your dll is running from.
HMODULE hModule = GetModuleHandleW(L"RunningDll.dll");
WCHAR path[MAX_PATH];
GetModuleFileNameW(hModule, path, MAX_PATH);
Then replace the base name of the dll with the name of the plugin.dll you want to load.
CString plugin(path);
int pos = plugin.Find(L"RunningDll.dll");
plugin = plugin.Left(pos);
plugin += L"pluginName.dll";
Call LoadLibrary on the generated string.