I have 2 compiled assemblies. Assembly A references assembly B.
I would like to change some code in assembly B. I would like to create a class library that impersonates assembly B in the eyes of assembly A. I want assembly A to continue working with my new types and namesspaces as if nothing ever happened.
Can I just create the new assembly with the same name and version number? Will assembly A assume that the new assembly is just like the old assembly B?
Assuming that the original assembly is not signed and the old assembly's interface is a subset of the new one's (could be the same), you should be ok. It would basically be the same as changing all the internals of B and possibly adding new methods without updating the version number.
Related
I am trying to import VB6's VBRUN type library into a Visual C++ 2017 header file, but it is failing due to a missing dependency.
Visual C++ reports
"error C4772: #import referenced a type from a missing type library;
'missing_type' used as a placeholder"
Viewing the file with OLE View reveals the problem is with the DataFormat property (DataFormat([out, retval] --<GetRefTypeInfo failed>** Return)).
The missing dependency would appear to be stdDataFormat: which type library does stdDataFormat reside in and why is it missing? (My operating system is Windows 10 Enterprise, 21H1.) Did I miss a selection when installing Visual Studio 6?
This addresses the first part of the question, how to find the typelib (TLB) containing a given interface or class.
Assuming you have no preconception about the TLB / DLL hosting a given COM interface or class you can find it by a couple of registry searches, assuming the type in question actually has been registered.
I started off in HKEY_CLASSES_ROOT with a search for data values = stdDataFormat. This lead to:
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat]
#="StdDataFormat Object"
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat\CLSID]
#="{6D835690-900B-11D0-9484-00A0C91110ED}"
Now armed with the CLSID GUID of 6D835690-900B-11D0-9484-00A0C91110ED, search for that value, finding:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED
of which its important sub-element for our purposes is:
[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED}\InprocServer32]
#="c:\\windows\\SysWow64\\msstdfmt.dll"
...
The InprocServer32 value was the main thing I wanted to find; it tells you the DLL - which is c:\windows\SysWow64\msstdfmt.dll (on my PC - but this should be typical).
Opening msstdfmt.dll in OLEView (or OLEViewDotNet) confirms this; the decompiled IDL from the TLB in that DLL contains:
[
uuid(6D835690-900B-11D0-9484-00A0C91110ED),
helpstring("StdDataFormat Object"),
helpcontext(0x00066b5f)
]
coclass StdDataFormat {
[default] interface IStdDataFormatDisp;
[default, source] dispinterface IStdDataFormatEvents;
};
So msstdfmt.dll should be the missing dependency.
If you did suspect this DLL to begin with, then obviously its a lot quicker to just load it in OLEView and check. But in many cases that won't be obvious when you're starting out.
As for the second part of the question - why is this dependency missing - maybe it would help if you added the relevant section of your code / includes?
I'm trying to write a plugin for 3ds max, I went through the entire sdk installation process to the letter as described in the help files.
The problem I'm facing though is intellisence complaining about an invalid macro definition
"IntelliSense: command-line error: invalid macro definition:_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT =1"
I found the definition in project settigs -> c/c++ -> preprocessor definitions as inherited from parent or project default.
I tried disabling the inherited definitions and re-entered them, this time without the space between the name and the = and all works fine so I'm guessing its a typo on their part?
Anyway, I want to change the default project or whatever to not repeat it every time i start a new project. The project is created with a wizard which required me to copy over some files to appear and after which I had to enter the sdk path.
The files I copied are plain text with some fancy extensions and not much in them so I'm guessing the defaults are described in the sdk directory.. somewhere. Does anybody know what kind of a file I'm looking for?
EDIT: I found a file called root.vcxproj_template and it has a section for preprocessor definitions but all it contains is
<PreprocessorDefinitions>_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
and no mention of the broken one
EDIT2: in another part of the file there was a path to a property sheet (maxsdk\ProjectSettings\propertySheets\3dsmax.common.tools.settings) which included the faulty definition. I fixed it an no more complaints from VS.
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 1 means that compiler should replace all old C run-time routines such as sprintf, strcpy, strtok with new versions such as strprintf_s, strcpy_s, strtok_s and similar. It goes in pair with following definition _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 1.
More you can find here: (MSDN) https://msdn.microsoft.com/en-us/library/ms175759.aspx. However I tried to use this but without success. It says that you can use this only for statically allocated buffers like char buffer[32], but compilers was still complaining bout unsecure strcpy.
I need to 'friend' a dll library that I didn't author.
I can see in the properties that it has a strong name, but how can I find out what the strong name is, so I can use it in System.Runtime.CompilerServices.InternalsVisibleTo?
To get the public key of a strong-named assembly, use the sn tool:
sn -Tp assembly.dll
This will show you the public key that you need to put in the InternalsVisibleTo attribute. If you open a Visual Studio command prompt, the sn.exe tool will already be in the path.
However, I would question what you are trying to actually achieve. If you have a compiled assembly that you did not write, adding the InternalsVisibleTo attribute to your code will let it access the internals of your code, but it wouldn't have compiled without already having friend access. If you are trying to access the internals of the other assembly, then the InternalsVisibleTo attribute will need adding to the other assembly - something which you cannot do without recompiling it..
You have to specify fully qualified name and public key token in AssemblyInfo.cs file of assembly you "need a friend":
[assembly: InternalsVisibleTo("FullAssemblyName, PublicKey=....", )]
If you have Reflector.NET or ildasm in hand you can use it to see this information
I am trying to compile a class(sqlAccess) declared as public with few methods related to database connection in it. I am getting the following error ...
Error 1 Friend access was granted to 'SqlAccess, PublicKey=00c8', but the output assembly is named 'SQLAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Try adding a reference to 'SqlAccess, PublicKey=00c8' or changing the output assembly name to match. c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll SQLAccess
What could be the reason? is there already a method of that name? I am new to programming so am unable to understand this clearly. Thank you.
This worked for me:
Open the Properties|Signing Tab. Ensure that you have "Sign the Assembly" checked and the strong name key file referenced. Save and compile the Project/Solution.
(cited from MSDN)
.NET seems to get grumpy if you give your assembly/project a name that isn't unique. In your case, SqlAccess must already exist in .NET or a referenced assembly.
The fix is to rename your assembly.
Similar issue:
Weird error in C#
That's because SqlAccess assembly has a reference which granted internal access to SqlAccess. It must be something like this [you will find it in AssemblyInfo.cs] :
[assembly: InternalsVisibleTo("Name of assembly goes here, PublicKey=")]
During compile time when compiler can not find assembly with specific PublicKey, you will get the error such as 'Friend access was granted to...'.
In order to resolve this problem one solution is to remove above attribute from source assembly, or add new public key and change it in source assembly.
Reason behind this should be either you have reinstall/update that particular dll within your solution and but old dll was not deleted properly from your solution and system.
That's why, it got worked when you change the Assembly name (from sqlAccess to sqlAccessXYZ)
I changed the Assembly name to sqlAccessXYZ and now its working, the problem is with the name. Not sure what exactly the problem, for now the issue is resolved. Thanks.
I have an old c++ project compiled with VC6.
I need to statically link a new library to implement a new functionality.
Unfortunately the new library define a symbol (i.e. _inflate) that is already defined in a previously linked static library.
Of course I cannot get rid of either library, and of course I have no access to the library's source code.
Is there a way to avoid the linker error (LNK2005)?
If you know that the two versions of _inflate are identical, or at least "compatible", then you can use the /FORCE:Multiple linker option to force it to ignore name clashes.
Of course, if it links to a version of that code that is "incompatible" in any way it could cause undefined behaviour.