C# 如何在运行时指定[DllImport]路径(嵌入在.msi文件中)
我想将一个dll导入到我的C#项目中,使用DllImport调用它的函数。 我有需要作为.msi文件一部分导入的dll 当我指定DLL的完整路径时,它确实起作用,但这在.msi文件之外C# 如何在运行时指定[DllImport]路径(嵌入在.msi文件中),c#,wix,windows-installer,dllimport,custom-action,C#,Wix,Windows Installer,Dllimport,Custom Action,我想将一个dll导入到我的C#项目中,使用DllImport调用它的函数。 我有需要作为.msi文件一部分导入的dll 当我指定DLL的完整路径时,它确实起作用,但这在.msi文件之外 我面临dllNotFoundException问题 <Binary Id="CustomAction2.CA.dll" src="../artifacts/CustomAction2.CA.dll" /> <CustomAction Id="Install"
我面临dllNotFoundException问题
<Binary Id="CustomAction2.CA.dll"
src="../artifacts/CustomAction2.CA.dll" />
<CustomAction Id="Install"
Execute="deferred"
BinaryKey="CustomAction2.CA.dll"
DllEntry="CustomAction1" />
<CustomAction Id="InstallWithProperty"
Property="Install"
Value="location=[DEFAULT_INSTALLDIR]$FULL_NAME;name=myDll.dll"
Execute="immediate"/>
<InstallExecuteSequence>
<Custom Action="InstallWithProperty" After="InstallFiles"/>
<Custom Action="Install" After="InstallWithProperty" />
</InstallExecuteSequence>
当调用自定义操作时,它会显示
我得到以下例外
自定义操作引发的异常:System.Reflection.TargetInvocationException:调用的目标已引发异常。-->System.DllNotFoundException:无法加载DLL“myDll.DLL”:找不到指定的模块。CustomAction2.CustomActions.ConfigDriver(IntPtr hwndParent、UInt16 fRequest、字符串lpszDriver、字符串lpszArgs、字符串lpszMsg、UInt16 cbMsgMax、Int64和pcbMsgOut)的CustomAction2.CustomActions.CustomAction1(会话)处的(HRESULT:0x8007007E异常)---内部异常堆栈跟踪的结尾---在System.RuntimeMethodHandle处。\ u在System.RuntimeMethodHandle.InvokeMethodFast处调用MethodFast(IRuntimeMethodInfo方法、对象目标、对象参数、SignatureStruct&sig、MethodAttributes方法属性、RuntimeType类型所有者)在System.Reflection.RuntimeMethodInfo.Invoke(对象对象对象、BindingFlags invokeAttr、绑定绑定器、对象参数、CultureInfo区域性、布尔skipVisibilityChecks)的System.Reflection.RuntimeMethodInfo.Invoke(对象对象对象、BindingFlags invokeAttr、Binder Binder、对象参数、CultureInfo区域性、布尔skipVisibilityChecks)中Microsoft.Deployment.WindowsInstaller.CustomActionProxy.InvokeCustomAction(Int32 sessionHandle,String entryPoint,IntPtr remotingDelegatePtr)CustomAction安装返回的实际错误代码为1603(注意,如果翻译发生在沙盒内部,则可能无法100%准确)
有人能帮忙吗。我想使用myDll.dll进行进一步安装,它是.msi文件的一部分。如果我理解正确,您的msi文件中有.dll,您想pInvoke它吗 不管你做这件事是为了什么,听起来很糟糕。你可能会重新思考你的方法, 然而,对于实际答案: 首先,这里有一点C代码: 现在请注意,它不会从MSI中提取文件,但这是一个好的开始。为了真正从MSI中提取,您需要稍微更改代码 下面是执行此操作的VB代码,请注意类似查询的SQL语法
Function ExtractIcon(IconName, OutputFile)
Const msiReadStreamAnsi = 2
Dim oDatabase
Set oDatabase = Session.Database
Dim View
Set View = oDatabase.OpenView("SELECT * FROM Icon WHERE
Name = '" & IconName & "'")
View.Execute
Dim Record
Set Record = View.Fetch
Dim BinaryData
BinaryData = Record.ReadStream(2, Record.DataSize(2),
msiReadStreamAnsi)
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Stream
Set Stream = FSO.CreateTextFile(OutputFile, True)
Stream.Write BinaryData
Stream.Close
Set FSO = Nothing
End Function
你需要把它转换成C#,这将是一项简单的任务。
之后,您需要实际使用dynamic pInvoke.Ps。如果您将DLL提取到项目文件夹中,并使用相对路径,则也可以使用普通pInvoke
要使用动态pInvoke,请执行以下操作:
遵循本文
这是一个简洁的代码:
using(UnmanagedLibrary lib = new UnmanagedLibrary("kernel32") // becomes call to LoadLibrary
{
Action<String> function = lib.GetUnmanagedFunction<Action<String>>("DeleteFile"); // GetProcAddress
function(@"c:\tmp.txt");
} // implict call to lib.Dispose, which calls FreeLibrary.
using(UnmanagedLibrary lib=newunmanagedlibrary(“kernel32”)//成为对LoadLibrary的调用
{
Action function=lib.GetUnmanagedFunction(“DeleteFile”);//GetProcAddress
函数(@“c:\tmp.txt”);
}//隐式调用lib.Dispose,它调用FreeLibrary。
如果你觉得自己是上帝,你可以将DLL加载到内存中,而不在任何地方提取它。如果你有一个神奇的DLL,它应该总是对任何人隐藏,这是很有用的。它只是为了提供信息-这是相当困难的^_^
using(UnmanagedLibrary lib = new UnmanagedLibrary("kernel32") // becomes call to LoadLibrary
{
Action<String> function = lib.GetUnmanagedFunction<Action<String>>("DeleteFile"); // GetProcAddress
function(@"c:\tmp.txt");
} // implict call to lib.Dispose, which calls FreeLibrary.