“игнорирование” P/Invoke при работе Моно

недостоверные исторические мелочи: "испытание с помощью дыма" прибывает из подводной разработки (наследованный от инфраструктуры), где литеральный дым был бы накачан в оболочку, чтобы видеть, вышел ли какой-либо из него снова, который был бы скорее поразительным отказом для подводной лодки!

5
задан Michael Stum 19 August 2009 в 19:45
поделиться

4 ответа

Почему бы не инкапсулировать платформенно-зависимый материал в интерфейс, а затем иметь какой-нибудь способ получить «правильную» реализацию для текущей платформы. Тогда вызывающий код сможет беззаботно использовать его, и вы можете постепенно заполнять биты для запуска в Mono, когда захотите. Я бы по крайней мере надеялся , что если вы даже не загрузите класс, содержащий биты P / Invoke, все будет в порядке ...

РЕДАКТИРОВАТЬ:

Я не понимаю, почему этот подход не должен не работает, хотя может и не нужен заводской. Вот что я бы сделал:

MainForm.cs:

PlatformServicesFacade.InitializeSystemMenu();

IPlatformServices.cs:

public interface IPlatformServices
{
    void InitializeSystemMenu();
}

MonoPlatformServices.cs:

public class MonoPlatformServices : IPlatformServices
{
    // Prevent early type initialization
    static WindowsPlatformServices() {}

    public void InitializeSystemMenu()
    {
        // Maybe log what you would have done?
    }
}

WindowsPlatformServices.cs:

public class WindowsPlatformServices : IPlatformServices
{
    // Prevent early type initialization
    static WindowsPlatformServices() {}

    public const Int32 SystemMenuAboutSWikiId = 1000;
    [DllImport("user32.dll")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
    [DllImport("user32.dll")]
    private static extern bool InsertMenu(IntPtr hMenu, Int32 wPosition, 
                                          Int32 wFlags, Int32 wIDNewItem,
                                          string lpNewItem);

    public void InitializeSystemMenu()
    {
        const Int32 MF_SEPARATOR = 0x800;
        const Int32 MF_BYPOSITION = 0x400;

        IntPtr systemMenuPtr = GetSystemMenu(Handle, false);
        InsertMenu(systemMenuPtr, 5, MF_BYPOSITION | MF_SEPARATOR, 0, "");
        InsertMenu(systemMenuPtr, 6, MF_BYPOSITION, SystemMenuAboutSWikiId, 
                   "About SWiki...");
    }
}

PlatformServicesFacade.cs:

public class PlatformServicesFacade
{
    private static readonly IPlatformServices services;

    static PlatformServiceFacade()
    {
        services = RunningOnWindows() ? new WindowsPlatformServices()
            : (IPlatformServices) new MonoPlatformServices();
    }

    public static void InitializeSystemMenu()
    {
        services.InitializeSystemMenu();
    }
}

Я думаю это должно сработать ... если не работает, расскажите, пожалуйста, что не так :)

8
ответ дан 18 December 2019 в 10:47
поделиться

Некоторые свойства Environment, вероятно, содержат эту информацию, например System.Environment.OSVersion.Platform. Или используйте if (Type.GetType ("Mono.Runtime")! = Null)

См. "Как определить платформу выполнения?" и «Как определить, работает ли я в Mono?»: http://www.mono-project.com/FAQ:_Technical

4
ответ дан 18 December 2019 в 10:47
поделиться

Проверка времени выполнения кажется жизнеспособным решением. Есть ли причина, по которой вы хотели бы удалить объявления функции P / Invoke, если они работают под Mono, даже если они никогда не используются?

2
ответ дан 18 December 2019 в 10:47
поделиться

Я думаю, ваш лучший выбор будет M / Invoke от парней из Mono. Он все еще довольно новый (только в Mono SVN). Но я уверен, что они хотели бы помочь с распространением моно :)

2
ответ дан 18 December 2019 в 10:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: