3

古いバージョンの SQL Server (2000) を使用しています。master.dbo.xp_cmdshell を実行する権限をユーザーに与えたくありません。ユーザーに実行権限を付与する独自の拡張ストアド プロシージャを作成するために使用できるカスタム DLL を作成しようとしています。

Visual Studio 2010 を使用して DLL を作成しています。これが私のヘッダーファイルstdafx.hです:

#define WIN32_LEAN_AND_MEAN 

#include <windows.h>
#include <iostream>

#ifndef INDLL_H
    #define INDLL_H

    #ifdef EXPORTING_DLL
        extern __declspec(dllexport) void HelloWorld() ;
    #else
        extern __declspec(dllimport) void HelloWorld() ;
    #endif
#endif

ここに私のメインファイルdllmain.cppがあります:

#include "stdafx.h"
#define EXPORTING_DLL

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                   LPVOID lpReserved)
{ return TRUE; }

void HelloWorld() {
    system("f:\\bin\\batchfilename.bat");
}

このプロジェクトをデバッグしようとすると、ビルドは成功しますが、「プログラムを開始できません: <コンパイル済み dll へのパス>」というエラーが表示されます。この DLL は動作すると思いますか? もしそうなら、動作するかどうかを自分でテストするにはどうすればよいですか?

4

2 に答える 2

3

OK、何時間もグーグルで調べた後、SQL Server 2000 拡張ストアド プロシージャとして追加する DLL のコンパイルに成功しました。グーグルで集めたものをまとめただけなので、ここで共有します。(Visual Studio 2010 を使用しました)。すべてを投稿するつもりはありません。Visual Studio で新しいプロジェクトを作成し、Win32 コンソール アプリケーション、次へ、DLL の順に選択することから始めました。いくつかのヘッダー ファイルとその他のファイルが作成されます。それらのいくつかは、私が必要だとは思わなかった. また、手動でプロジェクトに追加する必要があるヘッダー ファイルの一部。しかし、ここに私のメインの .cpp コードがあります:

#include "stdafx.h"         
#include "srv.h"   //Must get from C:\Program Files (x86)\Microsoft SQL Server\80\Tools\DevTools\Include            
#include "shellapi.h"  //need for ShellExecute          
#include "string"   //needed for std:string         
#include <sys/stat.h>  //need for stat in fileExists function below         

#define DLL_FUNC extern "C" __declspec (dllexport)          

__declspec(dllexport) ULONG __GetXpVersion() {          
   return ODS_VERSION;          
}           

bool fileExists(const std::string& filename) {          
    struct stat buf;            
    if (stat(filename.c_str(), &buf) != -1)         
    { return true; }            
    return false;           
}           

DLL_FUNC int __stdcall RunPP() {            
    if (fileExists("C:\\FileOnServer\\execute.bat")) {      
        ShellExecute(NULL,TEXT("open"), TEXT("C:\\FileOnServer\\execute.bat"), NULL, NULL,SW_SHOWNORMAL);       
        return 0;   
    } else {        
        MessageBox(HWND_DESKTOP, TEXT("File not found."), TEXT("Message"), MB_OK);  
        return 1;   
    }       
}           

コマンド ラインからrundll32 ({コンマの後にスペースなし}) を使用してこの DLL をテストできることを知りましたがrundll32 yourdllname.dll,functionname、プロジェクトに .def ファイルを含める場合に限られます。私のdefファイルは

LIBRARY
EXPORTS
RunPP

また、ドキュメントに記載されているように、[プロジェクト] > [プロパティ...] > [リンカー] > [入力] > [追加の依存関係] で Opends60.lib への参照を追加しようとしましたが、ある時点で削除されたようです。

私のような新参者のために、C/C++ > コード生成 > ランタイム ライブラリを /MD に切り替えるなど、プロジェクトのプロパティ ページで多くのことを学ばなければなりませんでした。また、リリース モードでコンパイルする方法、結果の .dll ファイルの場所なども学習します。

次に、コンパイルした DLL を SQL Server マシン (Win2003R2) に移動するときに、VC++ 2010 Redistributable をインストールして実行する必要がありました。次に、マシンの C:\Program Files\Microsoft SQL Server\MSSQL\Binn (xp_cmdShell 拡張ストアド プロシージャの DLL と同じ場所) に DLL をコピーし、ドキュメントに従って sp_addextendedproc を実行して、利用可能な拡張ストアとして登録しました。 master データベースのプロシージャ。次に、ユーザーがそれを実行する権限を付与します。

私はこれがすべて古い技術であることを知っています。SQL Server のバージョンをアップグレードする必要があります。しかし、多分これは他の誰かを助けるでしょう。

于 2012-10-05T22:24:45.220 に答える
0

次の 2 つのオプションがあります。

  1. DDL を「実行」する代わりに、実行中のプロセス sqlservr.exe にアタッチします。ブレーク ポイントを設定し、XP をロードします。デバッガーのブレークポイントが起動し、コードをステップ実行できます。

  2. プロジェクトの開始オプションを外部プログラムの開始に変更し、外部プログラムとして sqlservr.exe を選択します。

どちらのオプションでも、何をしているのか、特に 2 番目のオプションを知る必要があります (たとえば、サービスが停止していること、起動引数でインスタンス名を指定していること、SQL データディレクトリに適切にアクセスできることを確認してください)。

明らかに、SQL Server 2005 (少なくとも) にアップグレードし、代わりに SQLCLR を使用することをお勧めします。

于 2012-10-05T20:58:43.897 に答える