locked
Could not load file or assembly 'Interop.MSScriptControl' on Windows Server 2008 R2 Standard RRS feed

  • Question

  • Hi,

    I'm trying to add some scripting functionality to my server DLL.

    The DLL is run as part of an app server and some parameters passed in for the server to work on. Everything compiles correctly, however when I run the line in the code that touches MSScriptControl it cant find the assembly: 

    Could not load file or assembly 'Interop.MSScriptControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

    If I make the file local the app server cant cope and doesn't start. I don't know enough about the parent application to work around this.

    Can I copy the file somewhere in the windows directory? What is the best solution for this? The OS is

    Thanks

    • Moved by Leo Liu - MSFT Friday, March 2, 2012 6:08 AM Moved for better support. (From:Visual C# General)
    Thursday, March 1, 2012 12:03 PM

Answers

  • Set the target platform as x86.

    got to project properties and Build->Target Platform-> select x86.

    Hope this will solve your problem.

    • Marked as answer by Yev001 Monday, March 5, 2012 12:59 PM
    Thursday, March 1, 2012 12:26 PM
  • Thank you all for the help, I'm giving up on trying to make MSScriptControl work in a 64bit environment. I finished coding a rough alternative, for those interested see code below:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using Microsoft.VisualBasic;
    
    
    namespace CBIToolSyncServer
    {
        
        class ScriptHost
        {
            public static string Eval(string p_Code)
            {
                try
                {
                    string Code = p_Code;
                    string returnVal = "";
    
                    CodeDomProvider vbCompiler = new VBCodeProvider();
    
                    CompilerParameters compilerParams = new CompilerParameters();
                    compilerParams.GenerateExecutable = false;
                    
                    compilerParams.IncludeDebugInformation = false;
    
                    //set the filepath for the new assembly
                    compilerParams.TempFiles = new TempFileCollection(System.IO.Path.GetTempPath(), false);
                    compilerParams.GenerateInMemory = false; //<-- setting to true will delete temp dll after use
                    //add references
                    compilerParams.ReferencedAssemblies.Add("System.dll");
                    compilerParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
                    
                    //wrap the single line of code into a function
                    StringBuilder ScriptSB = new StringBuilder();
    
                    ScriptSB.Append(" Imports System \r\n");
                    ScriptSB.Append(" Imports System.Text \r\n");
                    ScriptSB.Append(" Imports Microsoft.VisualBasic \r\n");
                    ScriptSB.Append(" Namespace CBIToolSyncServer  \r\n");
                    ScriptSB.Append(" Class ScriptingHost \r\n");
                    ScriptSB.Append(" public function  EvalCode() as Object \r\n");
                    ScriptSB.Append(" Dim obj as Object \r\n");
                    ScriptSB.Append(" obj = " + p_Code + "\r\n"); //executes single line function
                    ScriptSB.Append(" Return obj \r\n");
                    ScriptSB.Append(" End Function \r\n");
                    ScriptSB.Append(" End Class \r\n");
                    ScriptSB.Append(" End Namespace \r\n");
    
                    //compile the code
                    CompilerResults results = vbCompiler.CompileAssemblyFromSource(compilerParams, ScriptSB.ToString());
                    if (results.Errors.Count == 0) //if sucessfully compiled
                    {
                        Assembly a = results.CompiledAssembly;
                        Object o = a.CreateInstance("CBIToolSyncServer.ScriptingHost");
                        Type t = o.GetType();
                        MethodInfo mi = t.GetMethod("EvalCode"); //grab the method from the compiled code
                        Object s = mi.Invoke(o, null); //execute the method (this returns an object)
    
                        returnVal = (string)s; //retun the object as string
                        return returnVal;
                    }
                    else //write code to return compile errors here
                        return "";
                }
                catch
                {
                    return "";
                }           
    
            }
        }
    }



    • Marked as answer by Yev001 Monday, March 5, 2012 12:59 PM
    • Edited by Yev001 Monday, March 5, 2012 1:05 PM
    Monday, March 5, 2012 12:58 PM

All replies

  • Set the target platform as x86.

    got to project properties and Build->Target Platform-> select x86.

    Hope this will solve your problem.

    • Marked as answer by Yev001 Monday, March 5, 2012 12:59 PM
    Thursday, March 1, 2012 12:26 PM
  • Set the target platform as x86.

    got to project properties and Build->Target Platform-> select x86.

    Hope this will solve your problem.

    Unfortunately not, I already tried this and the server fails to start. It is a 64 bit application. Setting it to x64 gives me a warning about an Oracle DLL I use:

    Warning 1 Assembly generation -- Referenced assembly 'Oracle.DataAccess.dll' targets a different processor CBIToolSyncServer

    And makes no difference (I still get the error).

    Thursday, March 1, 2012 12:31 PM
  • I think you are trying to use msscript.ocx which is 32bit dll and your application is 64bit. So far I know, a 64bit application can't load a 32bit dll.

    See these link

    http://stackoverflow.com/questions/5478904/32bit-dll-in-64bit-application-in-c-sharp

    http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/7b04ca15-7139-433a-ad3c-934a02175a5b/

    Thursday, March 1, 2012 1:01 PM
  • I don't think it's that simple. It uses the aforementioned Oracle DLL correctly, which is most certainly 32 bit. A lot of the applications own DLLs are written in runtime v2, and it only became 64bit last year.

    I don't know how it works, but referencing and using other 32bit DLLs in this way never presented a problem before.

    Thursday, March 1, 2012 1:12 PM
  • Hi Yev001,

    Try to use Foclogvw.exe to troubleshoot this problem. http://msdn.microsoft.com/en-us/library/e74a18c4.aspx

    It can tell how it tries to find the problematic assembly and why it fails.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Friday, March 2, 2012 6:09 AM
  • A bit more info on what I'm doing:

    Executing this: 

    strValue = Utilities.ExecuteMacro(strCode);
    
            public static string ExecuteMacro(string p_code)
            {
                //ScriptControl sctrl = new ScriptControl();
                ScriptControlClass sctrl = new ScriptControlClass();
                sctrl.Language = "VBScript";
                sctrl.AddCode("Function IIF( expr, v1, v2 ) If expr Then IIF = v1 Else IIF = v2 End If End Function");
    
                string result = null;
                try
                {
                    result = sctrl.Eval(p_code).ToString();
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Error in Code: *** " + p_code + " *** " + ex.Message, ex);
                }
    
                return result;
            }


    That is with these settings:

    If I leave it as Interop = True and use: ScriptControl sctrl = new ScriptControl();

    I get an error about assembly not registered. Being a complete newbie at this I have no idea if the above line is completely wrong way to do it or if I'm on the right path.

    Now the logs have no mention of MSScriptControl. Or anything else that fails (Set to "Log all binds to disk"):

    New logs only added during launch, nothing happens when I run the macro. This is the exception in full detail:

    System.IO.FileNotFoundException was caught
      Message=Could not load file or assembly 'Interop.MSScriptControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
      Source=CBIToolSyncServer
      FileName=Interop.MSScriptControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
      FusionLog==== Pre-bind state information ===
    LOG: User = CBI\LON-SRV-SCPX
    LOG: DisplayName = Interop.MSScriptControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
     (Fully-specified)
    LOG: Appbase = file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/
    LOG: Initial PrivatePath = E:\SPFConfig\Web_Sites\SPF_SCPX_DEVServer\bin
    Calling assembly : CBIToolSyncServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
    ===
    LOG: This bind starts in default load context.
    LOG: Using application configuration file: E:\SPFConfig\Web_Sites\SPF_SCPX_DEVServer\web.config
    LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
    LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
    LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
    LOG: The same bind was seen before, and was failed with hr = 0x80070002.
    
    
      StackTrace:
           at CBIToolSyncServer.Utilities.ExecuteMacro(String p_code)
           at CBIToolSyncServer.ToolAdapter.setProperty(String strCode, String strDestination, String strValue, ObjectWrapper SPFobj) in \\london-fs1\private$\ysnytserev\My Documents\Visual Studio 2010\Projects\CBIToolSyncServer\CBIToolSyncServer\ToolAdapter.cs:line 1173
           at CBIToolSyncServer.ToolAdapter.RunAdaptor(Boolean filterBySourceApp) in \\london-fs1\private$\ysnytserev\My Documents\Visual Studio 2010\Projects\CBIToolSyncServer\CBIToolSyncServer\ToolAdapter.cs:line 977
      InnerException: 

    Setting the file back to interop and changing to the line of code i commented out before: ScriptControl sctrl = new ScriptControl();

    I now get this log during startup:

    *** Assembly Binder Log Entry  (02/03/2012 @ 08:49:27) ***
    
    The operation failed.
    Bind result: hr = 0x80070002. The system cannot find the file specified.
    
    Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
    Running under executable  c:\windows\system32\inetsrv\w3wp.exe
    --- A detailed error log follows. 
    
    === Pre-bind state information ===
    LOG: User = CBI\LON-SRV-SCPX
    LOG: DisplayName = Interop.MSScriptControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
     (Fully-specified)
    LOG: Appbase = file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/
    LOG: Initial PrivatePath = E:\SPFConfig\Web_Sites\SPF_SCPX_DEVServer\bin
    LOG: Dynamic Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\spf_scpx_devserver\f3cc5923
    LOG: Cache Base = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\spf_scpx_devserver\f3cc5923
    LOG: AppName = c37d9bfa
    Calling assembly : CBIToolSyncServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
    ===
    LOG: This bind starts in default load context.
    LOG: Using application configuration file: E:\SPFConfig\Web_Sites\SPF_SCPX_DEVServer\web.config
    LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
    LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
    LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
    LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/spf_scpx_devserver/f3cc5923/c37d9bfa/Interop.MSScriptControl.DLL.
    LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/spf_scpx_devserver/f3cc5923/c37d9bfa/Interop.MSScriptControl/Interop.MSScriptControl.DLL.
    LOG: Attempting download of new URL file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/bin/Interop.MSScriptControl.DLL.
    LOG: Attempting download of new URL file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/bin/Interop.MSScriptControl/Interop.MSScriptControl.DLL.
    LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/spf_scpx_devserver/f3cc5923/c37d9bfa/Interop.MSScriptControl.EXE.
    LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/spf_scpx_devserver/f3cc5923/c37d9bfa/Interop.MSScriptControl/Interop.MSScriptControl.EXE.
    LOG: Attempting download of new URL file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/bin/Interop.MSScriptControl.EXE.
    LOG: Attempting download of new URL file:///E:/SPFConfig/Web_Sites/SPF_SCPX_DEVServer/bin/Interop.MSScriptControl/Interop.MSScriptControl.EXE.
    LOG: All probing URLs attempted and failed.
    

    System.Runtime.InteropServices.COMException was caught
      Message=Retrieving the COM class factory for component with CLSID {0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC} failed 
    
    due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 
    
    (REGDB_E_CLASSNOTREG)).
      Source=mscorlib
      ErrorCode=-2147221164
      StackTrace:
           at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& 
    
    canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
           at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
           at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean 
    
    skipCheckThis, Boolean fillCache)
           at System.Activator.CreateInstance(Type type, Boolean nonPublic)
           at CBIToolSyncServer.Utilities.ExecuteMacro(String p_code) in \\london-fs1\private$\ysnytserev\My Documents
    
    \Visual Studio 2010\Projects\CBIToolSyncServer\CBIToolSyncServer\Utilities.cs:line 125
           at CBIToolSyncServer.ToolAdapter.setProperty(String strCode, String strDestination, String strValue, 
    
    ObjectWrapper SPFobj) in \\london-fs1\private$\ysnytserev\My Documents\Visual Studio 2010\Projects
    
    \CBIToolSyncServer\CBIToolSyncServer\ToolAdapter.cs:line 1173
           at CBIToolSyncServer.ToolAdapter.RunAdaptor(Boolean filterBySourceApp) in \\london-fs1\private$\ysnytserev\My 
    
    Documents\Visual Studio 2010\Projects\CBIToolSyncServer\CBIToolSyncServer\ToolAdapter.cs:line 977
      InnerException: 
    

    Friday, March 2, 2012 8:56 AM
  • Hi Yev001,

    Thank you for your question.

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.
     
    Thank you for your understanding and support.


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, March 5, 2012 6:54 AM
  • Thank you,

    Reading a bit more on the issue I can't seem to find an answer. People generally say this should not work in 64 bit systems, it appears there is also a 64 bit DLL floating about with Vista 64. 

    As my deadline for this looms close I am in the process of trying to figure out how to create an alternative to MSScriptControl myself. But everything I look at seems to be obsolete.... VSA namespace, CodeDomProvider... And there are no clear examples or explanations as to how this works. I don't really need a COM, all I need is VBScript functions in a .net environment.

    I need to be able to let the user store a very small string script like "Left(#Val,3,1)" and the program to be able to execute it in a straightforward way. Is there some other way I can do this? Some way that is not obsolete?


    • Edited by Yev001 Monday, March 5, 2012 8:52 AM
    Monday, March 5, 2012 8:51 AM
  • Thank you all for the help, I'm giving up on trying to make MSScriptControl work in a 64bit environment. I finished coding a rough alternative, for those interested see code below:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using Microsoft.VisualBasic;
    
    
    namespace CBIToolSyncServer
    {
        
        class ScriptHost
        {
            public static string Eval(string p_Code)
            {
                try
                {
                    string Code = p_Code;
                    string returnVal = "";
    
                    CodeDomProvider vbCompiler = new VBCodeProvider();
    
                    CompilerParameters compilerParams = new CompilerParameters();
                    compilerParams.GenerateExecutable = false;
                    
                    compilerParams.IncludeDebugInformation = false;
    
                    //set the filepath for the new assembly
                    compilerParams.TempFiles = new TempFileCollection(System.IO.Path.GetTempPath(), false);
                    compilerParams.GenerateInMemory = false; //<-- setting to true will delete temp dll after use
                    //add references
                    compilerParams.ReferencedAssemblies.Add("System.dll");
                    compilerParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
                    
                    //wrap the single line of code into a function
                    StringBuilder ScriptSB = new StringBuilder();
    
                    ScriptSB.Append(" Imports System \r\n");
                    ScriptSB.Append(" Imports System.Text \r\n");
                    ScriptSB.Append(" Imports Microsoft.VisualBasic \r\n");
                    ScriptSB.Append(" Namespace CBIToolSyncServer  \r\n");
                    ScriptSB.Append(" Class ScriptingHost \r\n");
                    ScriptSB.Append(" public function  EvalCode() as Object \r\n");
                    ScriptSB.Append(" Dim obj as Object \r\n");
                    ScriptSB.Append(" obj = " + p_Code + "\r\n"); //executes single line function
                    ScriptSB.Append(" Return obj \r\n");
                    ScriptSB.Append(" End Function \r\n");
                    ScriptSB.Append(" End Class \r\n");
                    ScriptSB.Append(" End Namespace \r\n");
    
                    //compile the code
                    CompilerResults results = vbCompiler.CompileAssemblyFromSource(compilerParams, ScriptSB.ToString());
                    if (results.Errors.Count == 0) //if sucessfully compiled
                    {
                        Assembly a = results.CompiledAssembly;
                        Object o = a.CreateInstance("CBIToolSyncServer.ScriptingHost");
                        Type t = o.GetType();
                        MethodInfo mi = t.GetMethod("EvalCode"); //grab the method from the compiled code
                        Object s = mi.Invoke(o, null); //execute the method (this returns an object)
    
                        returnVal = (string)s; //retun the object as string
                        return returnVal;
                    }
                    else //write code to return compile errors here
                        return "";
                }
                catch
                {
                    return "";
                }           
    
            }
        }
    }



    • Marked as answer by Yev001 Monday, March 5, 2012 12:59 PM
    • Edited by Yev001 Monday, March 5, 2012 1:05 PM
    Monday, March 5, 2012 12:58 PM