I have an app (built with VS2003) that uses CompileAssemblyFromFile has been working just fine. Now when some users load NET 2.0 on their system it fails.
Doing a bit of research it looks like the parameters for this function have changed ->
NET 1.1 (An string containing the filename)
CompilerResults CompileAssemblyFromFile (
CompilerParameters options, string fileName);
NET 2.0 (An string array of filenames)
public virtual CompilerResults CompileAssemblyFromFile (
CompilerParameters options, string[] fileNames);
I know that the users will have NET v1.1 on their system if they are running my app.
How can I force the app to call to the v1.1 version of CompileAssemblyFromFile and not the 2.0 version
Thanks in advance for any input!
Zdog

CompileAssemblyFromFile parameter change in 2.0
Oliver Samson
You are correct that the .NET components are installed side-by-side and so in most cases should not conflict. I vaguely remember having a similar problem when I use to do dynamic compilation under v1.1. The problem was that the command line would not be properly built if the source had spaces in it. Unfortunately I can't duplicate it now. It might have had something to do with the assembly paths I was trying to use or something but I remember looking at the command line and realizing it was wrong.
Nevertheless the following code works in both v1.1 and v2.0.
CSharpCodeProvider prov =
new CSharpCodeProvider();ICodeCompiler icc = prov.CreateCompiler();
CompilerParameters options =
new CompilerParameters();options.GenerateExecutable =
true;options.OutputAssembly =
@"c:\temp\test path\main.exe"; string strFile = @"c:\temp\Test Path\main.cs";CompilerResults arr = icc.CompileAssemblyFromFile(options, strFile);
What compiler options did you specify What provider are you using If you are trying to generate an assembly on disk did you verify you had write access to the path What error are you getting exactly
Michael Taylor - 1/20/06
SBurris
Where did you see the definition in 2.0 In 2.0 the original member still exists on the ICodeCompiler interface. In 2.0 a new method called CompileAssemblyFromFile has been added to the CodeDomProvider class but it accepts a variable string array.
As for calling the 1.1 version you can only do that if you are targeting 1.1. The 2.0 version will be used if you are compiling against 2.0 because it is contained in System and there can be only one. You can force the version of .NET you use via the application configuration file.
Michael Taylor - 1/18/06
David465465454
What is the failure that you're seeing on the machines that have 2.0 installed Is an exception being thrown Is the code failing to compile
JZINK123
Yes, I do create a “Compiler” as in your code sample.
Your code (any mine) will work, unless...
If you have any <spaces> in the output file path it will fail !
String OutputFile = @” C:\Program Files\My Files\class1.cs";
CompilerResults res = icc.CompileAssemblyFromFile(options, OutputFile);
I thought that .NET was supposed to avoid having working code break if a "newer" version of the framework is installed. (aka. side-by-side install)
Zdog 1/29/06
alli
Could you perhaps post the code that calls this method Like I mentioned earlier CompileAssemblyFromFile() didn't exist prior to 2.0 on the CodeDomProvider class so you couldn't call it. You would have had to use CreateCompiler to create an instance of ICodeCompiler and then call CompileAssemblyFromFile() on the ICodeCompiler object. This mechanism still works in 2.0 although ICodeCompiler has been deprecated. However you might be seeing that the 2.0 implementation actually calls back into the new method.
I implemented the following code using v1.1 and ran it on a machine with v2.0 without any problems.
CSharpCodeProvider prov = new CSharpCodeProvider();
ICodeCompiler icc = prov.CreateCompiler();
CompilerParameters options = new CompilerParameters();
options.GenerateInMemory = true;
options.GenerateExecutable = true;
options.IncludeDebugInformation = true;
CompilerResults res = icc.CompileAssemblyFromFile(options, "class1.cs");
I recompiled the code against v2.0 and other than the obsolete warning it ran correctly.
Michael Taylor - 1/18/06
Mateus Stock
I apologize for the delay in posting.
We’re passing a fun virus around the group and the last week has been my turn. ;(
Access to the specified path is not the problem (it is using the users local\temp folder).
The error when run on a sysem with v2.0 loaded ->
Compiling file: "C:\Documents and Settings\username\Local Settings\Temp\~Wrapper.cs"
Source file 'and' could not be found at line0 column 0
Source file 'Settings\username\Local' could not be found at line0 column 0
Source file 'Settings\Temp\theRes.resources' could not be found at line0 column 0
Since it is refering to the resources file it may be related to the compiler options
Anyway, to "correct" it all I had to do as change the output to a folder that did not contain any spaces in its path and it runs fine. Just weird...
// NET v1.1 (built with VS 2003)
void Build(string codeCS, string resourceFileName, string refPath)
{
Stream s = File.Open(codeCS, FileMode.Create);
StreamWriter sw = new StreamWriter(s);
CSharpCodeProvider cscProvider = new CSharpCodeProvider();
ICodeCompiler compiler = cscProvider.CreateCompiler();
// Build the parameters for compilation
string [] referenceAssemblies = {Path.Combine(refPath, "myHook.dll")};
CompilerParameters cp = new CompilerParameters(referenceAssemblies);
cp.GenerateInMemory = false;
cp.OutputAssembly = Path.Combine(Path.GetTempPath(), "Wrapper.DLL")
cp.CompilerOptions = @"/resource:" + resourceFileName;
ICodeGenerator cscg = cscProvider.CreateGenerator(sw);
CodeGeneratorOptions cop = new CodeGeneratorOptions();
// The namespaces needed
CodeNamespace cns = new CodeNamespace("Wrapper");
cns.Imports.Add( new CodeNamespaceImport("System") );
// <snip> ... other namespaces... </snip>
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cns);
// <snip> ... code that gets compiled... </snip>
cscg.GenerateCodeFromNamespace(cns, sw, cop);
CompilerResults cr = compiler.CompileAssemblyFromFile(cp, codeCS);
}
Thanks for the input!
Zdog -1/25/06
Adam Braden - MS
Ah, there you go. It is clear as mud now :} The problem is that in your options you are specifying a resource file to compile as well through the cp.CompilerOptions member. The problem is that since your path contains spaces the output to the compiler looks like:
/resource:c:\Document and settings\username\Local Settings\temp\theRes.resources
See the problem. The compiler is going to pick up /resource:c:\Document as the resource and then sees and settings\username\Local, Settings\temp\theRes.resources as separate options. In this case it'll see them as source files to compile. You need to quote the string. CompilerOptions passes directly to the compiler so no translation is done. So change the above line to
cp.CompilerOptions = @"\resource:\"" + resourceFileName + "\"";
Then the compiler should see the line the way you really intended.
Michael Taylor - 1/25/06
Rob Adrian
>>Where did you see the definition in 2.0
I found it here -> http://msdn2.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.compileassemblyfromfile.aspx
>>In 2.0 a new method called CompileAssemblyFromFile has been added
>>to the CodeDomProvider class but it accepts a variable string array.
I thought that is what I'd stated The “new” version with the altered parameters is getting used instead of the v1.1 version that had been working fine.
What has caught me is the app is build using VS2003 with the v1.1 framework
(I only have v1.1. on my system) and been users have been successfully using the v1.1 version of CompileAssemblyFromFile.
Since the app is "targeted" at v1.1 and I know that any user of this app will have v.1.1 on their system. - Why does it try to use the "new" CompileAssemblyFromFile from the v2.0 on the end-users’ system
>> You can force the version of .NET you use via the application configuration file.
True, but since my app is built with v1.1 and the target machine has v1.1, I should not need a .config file - correct
Thanks for your input!
Zdog
1/18/06