tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルAddPrinterDriverがうまくいきません
記事No10255
投稿日: 2010/10/19(Tue) 23:21
投稿者zonk
プリンタドライバをインストールしたいのですが、「プリンタ名が無効です」と
表示されて上手くいきません。
AddPrinterDriverW を AddPrinterDriverA に変えると、エラーメッセージは
「パラメータが間違っています」になります。
どこがまずいかご教授お願いします。
環境はVista、VB2008です。

必要なファイルは事前に C:\Windows\system32\spool\DRIVERS\W32X86 にコピー済みで、
ファイルをフルパスで指定しても同じ結果になります。


Private Declare Function AddPrinterDriver Lib "winspool.drv" Alias "AddPrinterDriverW" _
                (ByVal pName As String, _
                ByVal Level As Integer, _
                ByRef pDriverInfo As DRIVER_INFO_3) As Integer

Public Structure DRIVER_INFO_3
    Public cVersion As Long
    Public pName As String
    Public pEnvironment As String
    Public pDriverPath As String
    Public pDataFile As String
    Public pConfigFile As String
    Public pHelpFile As String
    Public pDependentFiles As String
    Public pMonitorName As String
    Public pDefaultDataType As String
End Structure

Public Shared Function DriverInstall(ByVal strDriverName As String) As Boolean
    Dim di As New DRIVER_INFO_3
    With di
        .cVersion = 3
        .pConfigFile = "ps5ui.dll"
        .pDataFile = strDriverName & ".ppd"
        .pDependentFiles = "pscript.ntf" & vbNullChar _
                & "pscript.hlp" & vbNullChar _
                & "ps5ui.dll" & vbNullChar _
                & strDriverName & ".ppd" & vbNullChar _
                & "pscript5.dll"
        .pDriverPath = "pscript5.dll"
        .pEnvironment = "Windows NT x86"
        .pHelpFile = "pscript5.hlp"
        .pMonitorName = String.Empty
        .pName = strDriverName
        .pDefaultDataType = "RAW"
    End With

    If AddPrinterDriver(String.Empty, 3, di) = 0 Then
        Dim ExcptWin32 As New Win32Exception(Marshal.GetLastWin32Error())
        MessageBox.Show(ExcptWin32.Message, "Win32Err", MessageBoxButtons.OK)
        Return False
    End If
    Return True
End Function

[ツリー表示へ]
タイトルRe: AddPrinterDriverがうまくいきません
記事No10256
投稿日: 2010/10/19(Tue) 23:39
投稿者花ちゃん
> Public Structure DRIVER_INFO_3
>     Public cVersion As Long

試していないので解りませんが、変数の型が違っているのが影響しているとかありませんか?
      Public cVersion As Integer

[ツリー表示へ]
タイトルRe^2: AddPrinterDriverがうまくいきません
記事No10257
投稿日: 2010/10/20(Wed) 00:01
投稿者zonk
さっそくの返信、ありがとうございます。
ご指摘いただいた点を試してみたところ、

両方Integer型⇒現状通り
両方Long型  ⇒AddPrinterDriverAでもWでも「パラメータが間違っています」エラー

という結果になりました。

[ツリー表示へ]
タイトルRe^3: AddPrinterDriverがうまくいきません
記事No10258
投稿日: 2010/10/20(Wed) 07:43
投稿者花ちゃん
> 両方Long型  ⇒AddPrinterDriverAでもWでも「パラメータが間違っています」エラー

どうして Long 型 を使用されるのですか?
DWORD → Integer 
VB6.0 の Long 型 → .NET の Integer 型
になります。従って、参照している変数のアドレス等が狂ってしまい違うものを
参照している事になりませんか?
(間違った宣言でいくら試して見ても原因をつかむ事はできないかと思いますよ)

多分、VB6.0 のコードを参考に移植しようとされているのだと思うのですが、元のVB6.0の
コードのリンク等を貼るなりして頂けると問題点が解りやすいのですが、私の環境では
試す事ができないので...。

又、関数名で検索すれば、色々サンプル等も見つかりますし、下記等は参考になりませんか?

 http://www.vbforums.com/showthread.php?t=332405

 http://msdn.microsoft.com/ja-jp/library/cc428295.aspx

  http://wmifun.atinfinity.net/wmisample/win32_printerdriverb.html


[ツリー表示へ]
タイトルRe^4: AddPrinterDriverがうまくいきません
記事No10259
投稿日: 2010/10/20(Wed) 09:40
投稿者zonk
ご指摘ありがとうございます。

> 両方Integer型⇒現状通り
> 両方Long型  ⇒AddPrinterDriverAでもWでも「パラメータが間違っています」エラー

と書きました通り、Interger型で試したところ変化がなかったので、一応Long型でも
試してみました。

参考にしたのはC++のソースです。こちらのサイトを参考にさせていただいています。

http://dsas.blog.klab.org/archives/51741063.html

INFファイルはまだ試していませんでした。
今から仕事なので、帰宅後に試してみて報告いたします。

[ツリー表示へ]
タイトルRe: AddPrinterDriverがうまくいきません
記事No10260
投稿日: 2010/10/20(Wed) 10:49
投稿者魔界の仮面弁士
AddPrinterDriver の Level は、2, 3, 4, 6, 8 を指定できるはずですが、
今回使用するのは Lavel3 なのですね?


以下、掲示板に直書きしたコードです。未検証。

> Private Declare Function AddPrinterDriver Lib "winspool.drv" Alias "AddPrinterDriverW" _
>                 (ByVal pName As String, _
>                 ByVal Level As Integer, _
>                 ByRef pDriverInfo As DRIVER_INFO_3) As Integer

Private Declare Unicode Function AddPrinterDriver Lib "winspool.drv" _
   (ByVal pName As String, _
    ByVal Level As Integer, _
    ByRef pDriverInfo As DRIVER_INFO_3 _
  ) As <MarshalAs(UnmanagedType.Bool)> Boolean

'DRIVER_INFO_3 を Structure として実装した場合は ByRef pDriverInfo、
'DRIVER_INFO_3 を Class として実装した場合は ByVal pDriverInfo にします。
'戻り値は、元が BOOL 型なので Boolean 型にし、そこに UnmanagedType.Bool を付与します。


> Public Structure DRIVER_INFO_3
>     Public cVersion As Long
>     Public pName As String
>     Public pEnvironment As String
>     Public pDriverPath As String
>     Public pDataFile As String
>     Public pConfigFile As String
>     Public pHelpFile As String
>     Public pDependentFiles As String
>     Public pMonitorName As String
>     Public pDefaultDataType As String
> End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=4)> _
Private Structure DRIVER_INFO_3
    Public cVersion As UInteger
    Public pName As String
    Public pEnvironment As String
    Public pDriverPath As String
    Public pDataFile As String
    Public pConfigFile As String
    Public pHelpFile As String
    Public pDependentFiles As String
    Public pMonitorName As String
    Public pDefaultDataType As String
End Structure

'CharSet は Declare 側と一致させます(Ansi/Unicode/Auto)。
'Pack は…多分 4 で良いと思いますが未調査です。
'cVersion は、元が DWORD なので UInt32 か Int32 型にしてください。


>     Dim di As New DRIVER_INFO_3
Class なら New する必要がありますが、
Structure の場合は New は不要です。本題とは無関係ですが。


>     If AddPrinterDriver(String.Empty, 3, di) = 0 Then
ローカルにインストールする場合には、第 1 引数には
String.Empty ではなく、Nothing を指定してください。

[ツリー表示へ]
タイトルRe^2: AddPrinterDriverがうまくいきません
記事No10261
投稿日: 2010/10/20(Wed) 23:00
投稿者zonk
分り易く解説下さり、ありがとうございます。無事にドライバをインストールできました。
魔界の仮面弁士様にご指摘いただいた点に加え、更に2点修正しています。
・AddPrinterDriverのAPI宣言に Alias "AddPrinterDriverW" を付け加えました
・DRIVER_INFO_3のpDependentFilesプロパティの最後に & vbNullChar & vbNullChar を付けました

↓修正後のソース

Private Declare Unicode Function AddPrinterDriver Lib "winspool.drv" Alias "AddPrinterDriverW" _
           (ByVal pName As String, _
            ByVal Level As Integer, _
            ByRef pDriverInfo As DRIVER_INFO_3) As <MarshalAs(UnmanagedType.Bool)> Boolean

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=4)> _
Private Structure DRIVER_INFO_3
    Public cVersion As Int32
    Public pName As String
    Public pEnvironment As String
    Public pDriverPath As String
    Public pDataFile As String
    Public pConfigFile As String
    Public pHelpFile As String
    Public pDependentFiles As String
    Public pMonitorName As String
    Public pDefaultDataType As String
End Structure

Public Shared Function DriverInstall(ByVal strDriverName As String) As Boolean
    Dim di As DRIVER_INFO_3
    With di
    .cVersion = 3
    .pConfigFile = "ps5ui.dll"
    .pDataFile = strDriverName & ".ppd"
    .pDependentFiles = "pscript.ntf" & vbNullChar _
            & "pscript.hlp" & vbNullChar _
            & "ps5ui.dll" & vbNullChar _
            & strDriverName & ".ppd" & vbNullChar _
            & "pscript5.dll" & vbNullChar & vbNullChar
    .pDriverPath = "pscript5.dll"
    .pEnvironment = "Windows NT x86"
    .pHelpFile = "pscript5.hlp"
    .pMonitorName = String.Empty
    .pName = strDriverName
    .pDefaultDataType = "RAW"
    End With

    If Not AddPrinterDriver(Nothing, 3, di) Then
        Dim ExcptWin32 As New Win32Exception(Marshal.GetLastWin32Error())
        MessageBox.Show(ExcptWin32.Message, "Win32Err", MessageBoxButtons.OK)
        Return False
    End If
    Return True
End Function

[ツリー表示へ]