1

32 ビット プログラムで、ファイルを開く/保存ダイアログに 64 ビット システムの System32 フォルダ内のファイルを表示するにはどうすればよいですか?

Wow64DisableWow64FsRedirection何らかの理由でダイアログで機能しないため、機能しません。別のスレッド上にあるためだと思います。もちろんSysNative、ユーザーは内部で何が起こっているのかを認識していないため、使用は機能しません; 彼はコンピュータ上の「実際の」ファイルを見たいだけです。)


質問をする別の方法は次のとおりです。

ファイルを開くダイアログから 64 ビット フォルダを参照する32 ビット プログラムはありますか?System32

4

3 に答える 3

4

これは不可能だと思います。

ダイアログにファイルを表示できたとしても、32ビットプロセスに返されたときのファイルの名前は何でしょうか。Sysnativeはちょっとしたハックであり、いずれの場合もXP 64では使用できません。これは、system32名をオーバーロードした結果にすぎません。

別の思考実験。可能であれば、リダイレクトを無効にするために列挙を行うスレッドが必要になります。そのスレッドは制御不能であるため、それを無効にするための公開されたオプションが必要になります。ありません。32ビットプロセスがシェル拡張機能を読み込もうとしたときにDLLの読み込みに失敗するため、外部からのリダイレクトを無効にできるのは良くありません。DLLを読み込む場合は、リダイレクトを無効にすることはできません。間違ったもの

この制限を回避したい場合は、64ビットプログラムを作成することが期待されていると思います。

于 2011-03-09T07:50:55.130 に答える
1

これには有効な解決策があります。これは一種のハックですが、機能します。

解決策を示す前に、簡単な免責事項を述べます。私はヘファーマンにほぼ同意します。それは意図されたものではありません。実際には、配送コードに対してこれを行うことはお勧めしません。これは、32 ビットのテキスト エディター、ワープロ (32 ビットの Office を含む)、または通常のアプリがサポートしていないものです。64 ビット システムの通常のユーザーは、ファイルを直接システム ディレクトリで開いたり保存したりしません。そして、ほとんどの管理者以外のユーザーは、とにかくそこにあるファイルに触れるための適切な許可を持っていません. Microsoft は、32 ビット アプリの非常に正当な理由でファイル システムをリダイレクトします。それと戦おうとしないでください。

それでは解決策に進みましょう。

トリックは、DLL_THREAD_ATTACH コールバックごとに DllMain で DLL が Wow64DisableWow64FsRedirection を呼び出すようにすることです。

最初に、DllMain のみを持ち、"StartDisableRedirect" と "DisableRedirection" の 2 つの関数をエクスポートする単純な DLL を作成します。

bool g_fDisableRedirect = false;

__declspec(dllexport)
int DisableRedirection()
{
    void* pVoid = NULL;
    Wow64DisableWow64FsRedirection(&pVoid);
    return 0;
}


__declspec(dllexport)
int StartDisableRedirect()
{
    g_fDisableRedirect = true;
    return 0;
}



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        {
            void* pVoid = NULL;

            if (g_fDisableRedirect)
            {
                DisableRedirection();
            }
            break;
        }

    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

バイナリ (EXE または DLL) をこの DLL に直接リンクさせます。次に、GetOpenFileName を呼び出す直前に、StartDisableRedirect (後続のスレッドがリダイレクトされないようにするため) と DisableRedirect (現在のスレッド用) を呼び出します。

フックが実際にスレッドの処理を開始する前に、すべての DLL (システム DLL を含む) がロードされるように、意図的に「開始」関数を作成しました。Wow64Disable を実装する DLL が私の DLL の前にロードされるとは思いたくありませんでした。DllMain からコードを呼び出すときは、非常に注意する必要があります (読む: すべきではありません)。

extern int StartDisableRedirect();
extern int DisableRedirection();


void OnFile(HWND hwndParent)
{

    StartDisableRedirect();

    DisableRedirection();


    OPENFILENAME ofn = {};
    WCHAR szFile[MAX_PATH*2] = {};

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwndParent;
    ofn.lpstrFilter = L"All Files\0*.*\0\0";
    ofn.nFilterIndex = 1;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = ARRAYSIZE(szFile);
    ofn.Flags = OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;

    ::GetOpenFileName(&ofn);

}
于 2011-03-09T09:32:10.003 に答える
0

これは、インストーラーによくある問題です。人々は、32 ビット システムと 64 ビット システムの両方に対応する単一のインストーラー実行可能ファイルを出荷したいと考えています。つまり、32 ビットである必要があります。しかし、32 ビットのインストーラーは、64 ビットの実行可能ファイルを適切な場所に置くことができません。Raymond Chen によって説明されているように、解決策は、64 ビット マシン上の 32 ビット バージョンによって呼び出される別の 64 ビット インストーラーを持つことです。

アプリ ウィンドウを所有者として共通のダイアログを開くことをジョブとする 64 ビット プログラムを作成します。64ビットシステムでは、ダイアログを開くプロセスを作成し、渡すパラメーターなどを渡しますGetOpenFileName。stdout でファイル名をリッスンするか、他の IPC メカニズムを使用できます。Wow64DisableWow64FsRedirection返されたファイルを開くときに使用することを忘れないでください! UI を別のプロセスで実行するのは扱いにくいように思えるかもしれませんが、ユーザーにとってはシームレスであり、多くの Web ブラウザーはさまざまなプロセスでさまざまなタブやプラグインを実行します。

Vista 以降を問題なく使用できる場合は、ディレクトリIFileDialogに「場所」を追加できるインターフェイスを使用できます。SysNativeそうすれば、ユーザーは必要に応じて引き続きファイルにアクセスできます。誰かがSystem32ディレクトリをクリックしたときにSysNative代わりに移動するようにリダイレクトする簡単な方法さえあるかもしれません。

于 2011-03-09T10:15:59.407 に答える