官方不支持在托管代码中使用MAPI函数.显然,MAPI使用自己的内存管理,它在托管代码中崩溃和烧毁(请参阅此处和此处)
我想要做的就是启动包含主题,正文和一个或多个附件的默认电子邮件客户端.
所以我一直在研究MAPISendDocuments,它似乎工作.但我无法鼓起勇气在生产代码中实际使用该功能.
有没有人经常使用这个功能?你有恐怖故事吗?
PS.不,我不会用附件的命令行参数shellExecute Outlook.exe.
PPS.附件支持是必要条件,所以邮寄地址:解决方案不削减对我来说.
我有几个p /被调用的函数(但我现在正在重写我的代码所以我正在整理)我想知道如何使用/传递一个可空类型作为参数之一.使用int类型不是问题,但给出以下内容:
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, int? enumerator, IntPtr hwndParent, uint Flags);
Run Code Online (Sandbox Code Playgroud)
我希望能够将Guid参数作为可空类型传递.就目前而言,我可以将其称为:
SetupDiGetClassDevs(ref tGuid, null, IntPtr.Zero, (uint)SetupDiFlags.DIGCF_PRESENT );
Run Code Online (Sandbox Code Playgroud)
但我需要第一个参数也可以通过null.
我在使用基于Windows Mobile 5.0模拟器的基本方案时遇到了很多麻烦.我有一个winforms应用程序,最终调用本机代码.部署工作正常,所有本机DLL都复制到winforms .exe相同的文件夹中.我还验证了远程文件查看器工具的情况.
但是,当我启动我的应用程序时,它始终失败并显示"无法找到PInvoke dll - System.MissingMethodException"错误(当调用本机代码时,DllImport属性将变为无用).我知道本机dll与可执行文件位于同一文件夹中.我还应该做些什么?
我正在使用VS 2008.
我一直在努力从应用程序中隐藏任务栏中的另一个应用程序.
我一直在使用SetWindowLong函数来设置/删除扩展样式上的WS_EX_APPWINDOW .
我已尝试单独设置和删除属性以及获取当前WindowLong,并删除/添加到该属性,如下所示:
SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & WS_EX_APPWINDOW);
Run Code Online (Sandbox Code Playgroud)
并尝试删除它:
SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & ~WS_EX_APPWINDOW);
Run Code Online (Sandbox Code Playgroud)
在没有先让窗口长的情况下也尝试了这两种方法.这是我的整个代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[DllImport("User32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_HIDE = 0x00;
private const int SW_SHOW = 0x05;
private const int WS_EX_APPWINDOW = 0x40000;
private const …Run Code Online (Sandbox Code Playgroud) 我正在使用Windows服务中的CreateProcessAsUser(我们可以继续讨论主题,并假设我有充分的理由这样做).与其他人在这里问的问题相反,我在我的活动终端会话(会话1)中获得了一个窗口,而不是与服务(会话0)相同的会话 - 这是不可取的.
我挪用了斯科特艾伦的代码 ; 并想出了以下内容.值得注意的变化是"恢复自我","CREATE_NO_WINDOW"和命令行args支持.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security.Principal;
using System.ComponentModel;
using System.IO;
namespace SourceCode.Runtime.ChildProcessService
{
[SuppressUnmanagedCodeSecurity]
class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2; …Run Code Online (Sandbox Code Playgroud) 在尝试回答这个问题时,我决定在调试器视图中手动逐步完成编组过程.
不幸的是,Visual Studio似乎跳过了所有这些有趣的代码.这是对GetProfilesDirectory(WinAPI函数)的P/Invoke调用:

但是在接到这个电话(F11)后,我发现自己并没有FFF9BFD8; 相反,我在GetProfilesDirectory代码中着陆:

[Managed to Native Transition]堆栈上还有条目,暗示Visual Studio刚刚跳过一大堆代码.
我该如何逐步完成这一过渡?
我正在编写一个使用一些非托管代码的跨平台.NET库.在我的类的静态构造函数中,检测平台并从嵌入式资源中提取适当的非托管库并保存到临时目录,类似于另一个stackoverflow应答中给出的代码.
因此,当它不在PATH中时可以找到它,我在将它保存到临时文件后显式加载它.在Windows上,这可以LoadLibrary从kernel32.dll 正常工作.我正在尝试dlopen在Linux上做同样的事情,但是DllNotFoundException后来在加载P/Invoke方法时我得到了一个.
我已经验证库"libindexfile.so"已成功保存到临时目录并且调用dlopen成功.我钻研了单声道来源,试图弄清楚发生了什么,我想可能归结为是否随后的调用dlopen会重用以前加载的库.(当然假设我通过单声道源头的天真一举得出了正确的结论).
这是我正在尝试做的形状:
// actual function that we're going to p/invoke to
[DllImport("indexfile")]
private static extern IntPtr openIndex(string pathname);
const int RTLD_NOW = 2; // for dlopen's flags
const int RTLD_GLOBAL = 8;
// its okay to have imports for the wrong platforms here
// because nothing will complain until I try to use the
// function
[DllImport("libdl.so")]
static extern IntPtr dlopen(string filename, int …Run Code Online (Sandbox Code Playgroud) 考虑以下Win32 API结构:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
Run Code Online (Sandbox Code Playgroud)
将此对象移植到C#时,我应该遵循此处使用的名称命名约定,如下所示:
public struct _SECURITY_ATTRIBUTES
{
public int nLength;
public unsafe byte* lpSecurityDescriptor;
public int bInheritHandle;
}
Run Code Online (Sandbox Code Playgroud)
或者我可以全力以赴,并以C#样式编写我的结构,如下所示:
public struct SecurityAttributes
{
private int length;
private unsafe byte* securityDescriptor;
private int bInheritHandle;
public Int32 Length
{
get { return this.length; }
set { this.length = value; }
}
public Byte* SecurityDescriptor
{
get { return this.seurityDescriptor; }
set { this.securityDescriptor = value; }
}
public …Run Code Online (Sandbox Code Playgroud) 有关如何在运行时设置搜索目录的SO有一个很好的答案DllImport.使用两行代码可以正常工作.
但是,许多开源项目改为使用LoadLibrary函数.有传言称通过委托调用本机方法的速度较慢.我把它们称为"谣言",因为我只在两个地方看过这个,这无论如何都是微优化.
最有趣的地方是这篇博文:http://ybeernet.blogspot.com/2011/03/techniques-of-calling-unmanaged-code.html
在那里,作者测量了不同技术的表现:
NNanomsg使用功能的代表,但提到的博客文章与评论"的这比传统的P中的性能的影响/ Invoke的,显然不是好"在这条线.
来自MSFT的ASP vNext的Kestrel服务器使用与Libuv库相同的技术:这是代码
我认为代理使用比简单的DllImport更麻烦,并且考虑到性能差异,我想知道为什么面向性能的库使用委托代替设置dll搜索文件夹?
是否有任何技术原因,如安全性,灵活性或其他 - 或者这仅仅是品味问题?我不明白其理由 - 作者是否可能没有足够的搜索StackOverflow!?
我在C#中编写了一个模块,它导出了一些在C中使用的函数.我需要为C < - > C#之间的一些结构分配一些内存.
我在CI中分配的内容使用malloc,而在C#中我使用Marshal.AllocHGlobal()(分配非托管内存以传递给C).
如果我释放()使用Marshal.AllocHGlobal分配的内存,并且我使用malloc分配的Marshal.FreeHGlobal()释放内存,是否有任何问题?
谢谢